問題的由來
寫好的程序希望在崩潰之后能夠自啟動(dòng),于是利用linux的crontab功能,添加一個(gè)計(jì)劃任務(wù),每分鐘執(zhí)行一個(gè)腳本查看需要監(jiān)控的進(jìn)程是否還在,如果不在則啟動(dòng)之,否則不做任何事情。這么一個(gè)簡(jiǎn)單的腳本在crontab中運(yùn)行和在shell終端手工運(yùn)行的結(jié)果卻不一樣。
問題描述
以下是監(jiān)控腳本/home/watch.sh的內(nèi)容:
#!/bin/sh shell_log_file=/home/start.log pid_count=`pidof video_checkup | wc -w` path=$(cd "$(dirname "$0")"; pwd) run_command="${path}/video_checkup" config_path="${path}/config.json" if [ $pid_count -eq 0 ]; then echo `date +%Y-%m-%d_%H:%M:%S`" run $run_command $config_path" >> $shell_log_file $run_command $config_path else echo `date +%Y-%m-%d_%H:%M:%S`" video_checkup already running" >> $shell_log_file fi
在shell終端中執(zhí)行crontab -e 命令添加如下語句:
| 1 | */1* * * */home/watch.sh >/dev/null2>&1 |
表示該腳本每分鐘運(yùn)行一次,腳本的邏輯很簡(jiǎn)單就是檢查進(jìn)程video_checkup如不存在則運(yùn)行之,可是在實(shí)際測(cè)試中卻發(fā)現(xiàn),video_checkup進(jìn)程不斷增多,每分鐘都被運(yùn)行了一次。
問題分析
通過調(diào)試發(fā)現(xiàn)腳本中if [ $pid_count -eq 0 ]; then每次都會(huì)進(jìn)入并執(zhí)行video_checkup程序,也就是說$pid_count -eq 0這個(gè)判斷每次都是true。將 $pid_count 的值導(dǎo)入到log文件中發(fā)現(xiàn)確實(shí)是0 。
但是video_checkup明明在運(yùn)行的啊,不可能是0的,將watch.sh在shell命令行上手工執(zhí)行卻是正常的結(jié)果($pid_count就是實(shí)際的正在運(yùn)行的video_checkup進(jìn)程個(gè)數(shù)的值)。經(jīng)過google發(fā)現(xiàn),在crontab計(jì)劃任務(wù)中執(zhí)行腳本watch.sh的環(huán)境變量,和自己ssh登錄到shell中手工執(zhí)行watch.sh的環(huán)境變量是不同的,于是乎在watch.sh中加入下面的語句:
echo `export` >> $shell_log_file并分別在crontab中執(zhí)行watch.sh,以及在ssh登錄的shell中手工執(zhí)行watch.sh發(fā)現(xiàn)果然export的結(jié)果不一樣。
在crontab中執(zhí)行watch.sh的時(shí)候log文件中顯示的export結(jié)果中PATH的值是:export PATH="/usr/bin:/bin"
而ssh登錄到shell之后手工執(zhí)行watch.sh之后log文件中顯示的export結(jié)果中的PATH的值是:PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"這個(gè)影響大嗎,難道這個(gè)PATH變量對(duì)pid_count=`pidof video_checkup | wc -w`執(zhí)行的結(jié)果會(huì)有影響?
此時(shí)我想到有一種可能就是,pidof命令是在哪個(gè)目錄下? 在ssh的shell環(huán)境中執(zhí)行:
[root@172-28-246-152 video_checkup]# which pidof /sbin/pidof
發(fā)現(xiàn)pidof命令是在 /sbin/目錄下,也就是說crontab運(yùn)行的環(huán)境中 PATH="/usr/bin:/bin" 目錄中根本沒有pidof這個(gè)命令,那么在crontab中執(zhí)行 watch.sh中的pid_count=`pidof video_checkup | wc -w`就會(huì)失敗,但是居然連一個(gè)錯(cuò)誤都沒有報(bào)告,而且pid_count變量中還被賦值了,難道pidof命令找不到的時(shí)候這個(gè)語句也能返回值?
我在ssh的shell中構(gòu)造一個(gè)不存在的pidof路徑,試一下:
[root@172-28-246-152 video_checkup]# pid_count=`/xx/pidof video_checkup | wc -w` -bash: /xx/pidof: No such file or directory
果然報(bào)錯(cuò)說No such file or directory找不到命令,但是此時(shí)pid_count中是否有值呢? 再試一下:
[root@172-28-246-152 video_checkup]# pid_count=`/xx/pidof video_checkup | wc -w` && echo $pid_count -bash: /xx/pidof: No such file or directory 0
結(jié)果徹底清楚了: 由于crontab在后臺(tái)運(yùn)行,所以pidof命令不存在,我們根本看不到報(bào)錯(cuò)信息,因?yàn)閳?bào)命令不存在的信息是不會(huì)被通過管道傳遞給 wc -w 的,所以可以說出錯(cuò)的時(shí)候wc -w沒有收到任何輸入,但是其執(zhí)行的結(jié)果卻是 0 那么變量pid_count的值就是 0 了。
問題解決
將ssh登錄之后的shell環(huán)境中的PATH賦值到watch.sh腳本中即可,這樣腳本在運(yùn)行的時(shí)候就可以正確找到 pidof 命令得出正確的結(jié)果了 (也即在腳本watch.sh的開始處加入代碼PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"即可)
一個(gè)小問題居然花了幾個(gè)小時(shí)查清楚原因,可見平時(shí)覺得簡(jiǎn)單的問題在實(shí)際應(yīng)用過程中還是有很多坑的
鏈接:https://www.cnblogs.com/wangqiguo/p/5399227.html
-
Linux
+關(guān)注
關(guān)注
88文章
11803瀏覽量
219455 -
程序
+關(guān)注
關(guān)注
117文章
3847瀏覽量
85425 -
腳本
+關(guān)注
關(guān)注
1文章
411瀏覽量
29265
原文標(biāo)題:Linux計(jì)劃任務(wù)crontab運(yùn)行腳本不正確的問題
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
linux的定時(shí)任務(wù)設(shè)置和crontab配置
Linux應(yīng)用--日志定時(shí)清理
詳解linux定時(shí)任務(wù)
stm32單步執(zhí)行正常,全速運(yùn)行結(jié)果不正確怎么解決
Linux下自動(dòng)運(yùn)行crontab用法說明
Linux任務(wù)調(diào)度crontab時(shí)間規(guī)則介紹
關(guān)于stm32單步執(zhí)行正常,全速運(yùn)行結(jié)果不正確(時(shí)鐘配置不正確)的問題
淺析Wireshark流量添加計(jì)劃任務(wù)行為檢測(cè)
Crontab:簡(jiǎn)單實(shí)用的Python 周期任務(wù)調(diào)度工具
使用crontab定時(shí)執(zhí)行腳本
ie瀏覽器限制運(yùn)行腳本
linux定時(shí)任務(wù)的用法總結(jié)
Linux計(jì)劃任務(wù)介紹
Linux計(jì)劃任務(wù)cron詳解
Linux計(jì)劃任務(wù)crontab運(yùn)行腳本不正確的問題
評(píng)論