原文地址:https://lujun9972.github.io/blog/2020/04/08/crontab中的%/index.html
故障
某日定義了一個crontab定時運行一個檢查腳本,然把結果存在以 年月日時分秒
爲後綴的結果文件中,像這樣:
*/10 * * * * /path/to/check.sh >/tmp/results.$(date +%Y%m%d-%H%M%S)
然而並沒有起作用,在/tmp/下並沒有生成results文件。
排查
一開始以爲是crond服務沒有開,查看 cronie.service
狀態發現服務是active的. crond
進程也是running狀態的
systemctl status cronie.service
● cronie.service - Periodic Command Scheduler Loaded: loaded (/usr/lib/systemd/system/cronie.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2020-04-09 10:39:51 HKT; 3min 48s ago Main PID: 733593 (crond) Tasks: 3 (limit: 4433) Memory: 397.6M CGroup: /system.slice/cronie.service ├─733593 /usr/bin/crond -n └─733597 /usr/bin/CROND -n
用 ps
命令也能確認 crond
進程的存在:
ps -elf |grep crond |grep -v grep
4 S root 733593 1 0 80 0 - 2413 - 10:39 ? 00:00:00 /usr/bin/crond -n
無奈之下翻閱 man crontab
,發現在其中有這麼一段話:
The "sixth" field (the rest of the line) specifies the command to be run. The entire command portion of the line, up to a newline or a "%" character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the cronfile. A "%" character in the command, unless escaped with a backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.
也就是說,crontab命令中的 %
會被當成回車來看待,而且 %
後的內容會作爲該命令的標準輸入.
所以命令 /path/to/check.sh >/tmp/results.$(date +%Y%m%d-%H%M%S)
就變成了
/path/to/check.sh >/tmp/results.$(date +<<EOF Y%m%d-%H%M%S) EOF
在執行時就會提示 unexpected EOF while looking for matching `)'
解決
解決的方法是在 %
前加上反斜槓(\)進行轉義就可以了。