問題描述
開發時遇到個問題:使用 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啦