感謝 @Larva 在評論區的評論,大家可以採用他說的簡單的方式
你新建個使用者放 www-data 組就完事了。你搞複雜了
===== 以下是原文 =========
其實這個沒啥好說的,就是記錄下解決的過程(說得好像跟一篇水文似的…)。或者給遇到這類問題的小夥伴提供個思路。
痛點
我們在部署 web 服務時,經常用到定時任務。正常的流程就是直接執行下面的指令來配置定時任務
crontab -e
問題來了,正常情況下,這個指令在哪個使用者下面執行,這個許可權就是誰的(如果你聽不懂我在說啥,那基本就是屬於 root的)。
定時任務本身的配置也是個精細活,你可以閱讀下 部落格:你一定是用了假的 Linux cron 看看你之前用的姿勢是不是還能最佳化。
常見問題之日誌許可權
這怕是最常見的問題了。定時任務出錯了,記錄日誌到 storage/logs
裡了,一般就是 laravel.log
檔案。
此時 laravel.log
所屬者就是 root 了。
使用者透過瀏覽器訪問我們網站,如果出錯,以 www-data 身份嘗試記錄到 storage/logs/laravel.log
,然後寫不進去,一直報錯,真香!
解決
開啟谷歌搜尋 run cron job as www-data
。找到了文章 askubuntu.com/questions/189189/how...
谷歌真香!
具體的意思,就是直接在 /etc/crontab
中編輯定時任務即可,加上使用者名稱。
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
# cron
* * * * * www-data flock /tmp/flock1.lock -c 'timeout 200 /usr/local/bin/php /var/www/html/laravel/artisan command >> /home/log/laravel.log 2>&1'
囉嗦下:
- flock 用來防止重複執行,起到原子鎖作用
- timeout 表示這個指令碼執行過長,我們就乾死它,可以有效避免各種迴圈或長時間佔用問題
->>
表示向檔案中追加內容-2>&1
表示無論錯誤與否,都可以執行
關於劃線的兩個表述,感謝 @godruoyi 在評論區指正,大家可以看評論區,我摘錄如下:
>>
表示向檔案中追加內容>&1
表示無論錯誤與否,都可以執行
上面這兩點其實表述是不正確的:
>
表示覆蓋追加>>
表示尾部追加
這兩個管道運算子,在執行期間發生錯誤時,是不會將錯誤輸出寫入後面的「檔案」中的。在 Linux 系統中 0、1、2 分別表示不同的裝置型別,其中
0 標準輸入裝置,指鍵盤
1 標準正確輸出裝置
2 標準錯誤輸出裝置php artisan command >> /home/log/laravel.log 2>&1'
上面命令的意思是將
php artisan command
的 標準正確輸出 重定向到laravel.log
檔案。
而後面的2>&1
是表示將標註錯誤輸出重定向到標準正確輸出。從而達到錯誤輸出和正確輸出都記錄在
laravel.log
檔案中。
嗯。。。香!
真香後傳(更新於 2019年11月06日19:38:27)
如果你按照上述的進行,你會發現還是執行不了定時任務。因為 www-data
預設是不能執行 bash 相關操作的。
使用真香的谷歌搜尋 www-data run cron error
,我們發現了寶藏 ubuntuforums.org/showthread.php?t=...
The www-data user is not able to invoke a shell by default. In /etc/passwd you’ll see
Code:\ www-data33www-data:/var/www:/usr/sbin/nologin\ If you want to be able to run scripts as that user, you’ll need to change “/usr/sbin/nologin” to “/bin/bash”.
好了,我們們把 /etc/passwd
裡面 www-data
對應的那一行改下就可以了。
另外
其實你還可以用 crontab -u www-data CRON_FILE
來指定使用者執行指定的定時任務。
本作品採用《CC 協議》,轉載必須註明作者和本文連結