首頁  >  文章  >  運維  >  Linux crond不執行的原因

Linux crond不執行的原因

小云云
小云云原創
2018-03-20 14:04:552851瀏覽

為了定時監控Linux系統CPU、記憶體、負載的使用情況,寫了Linux Shell腳本,當達到一定值得時候,定時發送郵件通知。但是,讓crond來週期性執行腳本發送郵件通知時,遇到了問題,在crontab -e裡面加入了執行腳本之後,發現腳本並沒有執行。

可是,透過手動執行Shell腳本指令(./mimvp-email.sh)是正常的,因為手動執行腳本可以預設取得Linux的環境變量,但透過Crontab做的定時任務,則無法取得環境變數。

分析了原因,crond不執行的原因主要有以下幾個面向:

1、crond服務沒啟動

ps -ef | grep -v grep | grep crond         // 查看crond服务是否运行
service crond start           //关闭服务
service crond stop           //关闭服务
service crond restart       //重启服务
service crond reload       //重新载入配置

2、使用者沒有執行crond的權限

vim  /etc/cron.deny 檔案用來控制哪些使用者不能執行crond服務的功能。

可以將自己從檔案中刪去,或是聯絡root

3、crontab不提供所執行使用者的環境變數

解決方法:在腳本中加入下面這一行:

. /etc/profile
. ~/.bash_profile

4、沒有使用絕對路徑

這裡的絕對路徑包括腳本中的路徑和crond指令中的路徑兩面,例如:

*/10 * * * * sh /root/script/mysql_files_monitor.sh &

5、如果上面都沒有解決問題的話可以再找出問題:

1)去郵件看看,在這個過程中使用者應該會收到郵件,例如收到這樣的提示:

vim /var/spool/mail/root

You have mail in /var/spool/mail/root

去看看裡面就有crond的內容

檔案太大打不開,可以截取最後1000行檢視

tail -n 1000 /var/spool/mail/root > aaa.txt  &&  vim aaa.txt

2)在腳本裡面加入output用來調試

可以在crontab的腳本裡面加入個

echo $PATH > /tmp/test.log

比較和終端機下執行腳本的echo $PATH

#6 、crond行程太多,全部殺死重啟crond服務

#!/bin/bash
for i in $(ps -elf | grep -v grep | grep crond | awk -F " " ' {print $4}' ); do
     kill -9  $i
done

使用root執行重啟,後問題解決:

#service crond restart

7.crond防止腳本週期內未執行完重複執行

個人體會: flock -xn my.lock cmd
my.lock是一個文件,可以是任意文件,可以新建一個空文件
當flock 取得鎖定後就會執行後面的cmd

測試過程:

$1: flock -xn my.lock sleep 20
$2: flock -xn my.lock ls

只有當1回傳後,2的ls才會成功

如果某腳本要執行30分鐘,可以在Crontab裡把腳本間隔設為至少一小時來避免衝突。而比較糟的情況是可能該腳本在執行週期內沒有完成,接著第 二個腳本又開始運作了。如何確保只有一個腳本實例運作呢?一個好用的方法是利用lockf(FreeBSD 8.1下為lockf,CentOS  5.5下為flock),在腳本執行前先偵測能否取得某個檔案鎖,以防止腳本執行衝突。

lockf 參數如下

-k:一直等待取得檔案鎖定。

-s:silent,不發出任何訊息,即使拿不到檔案鎖定。

-t seconds:設定timeout的時間是seconds秒,如果超過時間,則自動放棄。

以下crontab計畫任務執行前,需取得暫存檔案create.lock 檔案鎖定,crontab計畫任務的內容如下:

1 */10 * * * * (lockf -s -t 0 /tmp/create.lock /usr/bin/python /home/project/cron/create_tab.py  >> /home/project/logs/create.log 2>&1)

#若第一第個實例在10分鐘內沒有運行完,第2個實例不會運作。我以前是透過Shell腳本來解決這個問題的,例如用while...do循環,然後放在後台執行。但後來發現其實用flock或lockf方法比較簡單。

附上linux下的flock的用法:

flock (util-linux 2.13-pre7)
Usage: flock [-sxun][-w #] fd#
       flock [-sxon][-w #] file [-c] command...
  -s  --shared     Get a shared lock 
#共享锁,在定向为某文件的FD上设置共享锁而未释放锁的时间内,其他进程试图在定向为此文件的FD上设置独占锁的请求失败,而其他进程试图在定向为此文件的FD上设置共享锁的请求会成功
  -x  --exclusive  Get an exclusive lock 
#独占或排他锁,在定向为某文件的FD上设置独占锁而未释放锁的时间内,其他进程试图在定向为此文件的FD上设置共享锁或独占锁都会失败。只要未设置-s参数,此参数默认被设置
  -u  --unlock     Remove a lock 
#手动解锁,一般情况不必须,当FD关闭时,系统会自动解锁,此参数用于脚本命令一部分需要异步执行,一部分可以同步执行的情况
  -n  --nonblock   Fail rather than wait 
#为非阻塞模式,当试图设置锁失败,采用非阻塞模式,直接返回1,
  -w  --timeout    Wait for a limited amount of time
#设置阻塞超时,当超过设置的秒数,就跳出阻塞,返回1
  -o  --close      Close file descriptor before running command
  -c  --command    Run a single command string through the shell 执行其后的comand
  -h  --help       Display this text
  -V  --version    Display version
举个例子执行如下脚本:

每天23:30的时候执行一个脚本,但是执行前必须要获得排他文件锁,否则无法执行命令

1 30 23 * * * flock -xn /tmp/test.lock -c '/usr/local/php test.php'

8、; 和 && 区别

“;” 和 “&&”是有区别的

“;”:不管cmd1执行的结果如何,都执行cmd2

“&&”:只有cmd1执行返回的结果是成功的,才执行cmd2

cmd1 && cmd2; cmd3

- cmd1 is executed, if it succeeds, then execute cmd2. and then cmd3 (regardless of cmd2 success or not)

- cmd1 is executed, if it fails, then cmd3 (cmd2 won't be executed)

9、如果遇到shell语法错误

Syntax error: "(" unexpected

解决方法:

需指定shell解释器命令:SHELL=/bin/bash(请参见上面 crontab编辑示例 SHELL=/bin/bash)

或者参见: LINUX - BASH Syntax Error

如果遇到路径错误

在 /var/spool/crontab/yanggang 中,添加了如下命令,在日志文件 /var/spool/mail/yanggang 中提示找不到 xxx.sh 路径

30 * * * *  /home/barry/top800/top10/top10_fruits/top10_all.sh

30 * * * * bash /home/barry/top800/top10/top10_fruits/top10_all.sh

这是因为你在crontab中使用了绝对路径执行脚本 top10_all.sh,因此在脚本 top10_all.sh 中引用的其它脚本也都需要使用绝对路径,才能被crontab找到并执行。

那么该如何避免绝对路径呢,推荐采用如下格式:

30 * * * * cd /home/barry/top800/top10/top10_fruits/ && ./top10_all.sh(推荐用此方式)

先进入该目录,然后在执行脚本;否则,执行脚本中的其它脚本都需要加绝对路径

参考推荐:

CentOS 7.2上 crontab 计划任务

linux定时运行命令脚本——crontab

CentOS crontab 定时任务不执行的解决

WordPress定时任务(wp-cron.php)造成主机CPU超标解决办法。

以上是Linux crond不執行的原因的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn