php-fpm臨時文件路徑問題(Sytemd PrivateTmp的坑)

問題描述

開發時遇到個問題:使用 shell_exec('echo 123 >> /tmp/test.txt') ,執行成功沒有報錯,但是並沒有寫入文件,且由於輸出到了 /tmp/test.txt 文件中,所以也沒有返回值,一直困擾什麼原因,起初懷疑是shell_exec() 的問題,查看php.ini的禁用函數設置,沒有問題;查看用戶及文件權限,也都沒有問題。

進而使用 file_put_contents(‘/tmp/test.txt’, 123) 進行寫入,執行依舊無誤,但依舊沒有成功寫入/tmp/test.txt文件。

這時候使用 file_get_contents('/tmp/test.txt') 嘗試獲取內容,發現可以獲取到之前的寫入,因此懷疑是文件路徑問題,寫入到了另一個位置。但是使用的是絕對路徑,那麼只可能在php-fpm的配置文件中找一找,因爲cli執行是沒問題的,說明與php.ini文件無關(這裏我已經確認了cli和cgi的方式使用的同一個php.ini文件)。

但是php-fpm.conf中並沒有相關設置,很是頭疼,因爲我印象中也沒有那個設置項有相關作用。於是嘗試到php-fpm.service中查看有沒有線索,結果真的發現了PrivateTmp = true 這個設置,導致我的臨時文件目錄由/tmp變爲了/tmp/systemd-private-xxx-php-fpm.service/tmp

原因是什麼

只要使用Systemd這個進程作爲啓動進程的linux系統,其子進程都會有PrivateTmp這麼一個屬性,就可以設置使用共享的tmp目錄。

nginx會有一個systemd-private-xxx-nginx.service/tmp目錄
php-fpm會有一個systemd-private-xxx-php-fpm.service/tmp目錄

PrivateTmp屬性有什麼好處

/tmp是所有用戶和服務共享的目錄,都有讀寫權限,那就存在安全性問題,所以每個服務將tmp目錄隔離,能保證一定的安全性。每個服務在啓動的時候創建目錄,停止的時候刪除目錄,好處是不需要單獨寫定期刪除臨時文件的腳本了

如何設置PrivateTmp屬性

如果要補充php-fpm的PrivateTmp,首先用systemctl找到服務對應路徑

systemctl status php-fpm

編輯xxx.service文件,找到PrivateTmp,修改PrivateTmp = false就OK啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章