嗯,真香!使用 www-data 使用者執行定時任務(cron)

rovast發表於2019-11-04

感謝 @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-data:x:33:33:www-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 協議》,轉載必須註明作者和本文連結

相關文章