Home  >  Article  >  Operation and Maintenance  >  Reasons why Linux crond does not execute

Reasons why Linux crond does not execute

小云云
小云云Original
2018-03-20 14:04:552851browse

In order to regularly monitor the usage of CPU, memory, and load of the Linux system, a Linux Shell script is written. When a certain value is reached, email notifications are sent regularly. However, when I asked crond to periodically execute the script to send email notifications, I encountered a problem. After adding the execution script to crontab -e, I found that the script was not executed.

However, it is normal to manually execute the Shell script command (./mimvp-email.sh), because manually executing the script can obtain the Linux environment variables by default, but it cannot be obtained through scheduled tasks done by Crontab. environment variables.

After analyzing the reasons, the main reasons why crond does not execute include the following aspects:

1. The crond service is not started

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

2. The user does not have the authority to execute crond

vim /etc/cron.deny file is used to control which users cannot execute the crond service function.

You can delete yourself from the file, or contact root

3. Crontab does not provide the environment variables of the executed user

Solution: Add the following to the script One line:

. /etc/profile
. ~/.bash_profile

4. No absolute path is used

The absolute path here includes the path in the script and crond There are two aspects of the path in the command, for example:

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

5. If the above does not solve the problem, you can try again Find the problem:

1) Check the email. During this process, the user should receive an email, such as this prompt:

vim /var/spool/mail/root

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

Go and see if there is crond content in it

The file is too big to open, you can intercept the last 1000 Line view

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

2) Add output to the script for debugging

You can add a

echo $PATH > /tmp/test.log

in the crontab script and compare it with the echo $PATH

6 of executing the script under the terminal , there are too many crond processes, kill them all and restart the crond service

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

Use root to perform a restart, and the problem is solved:

service crond restart

7. crond prevents repeated execution before the script is completed within the cycle

Personal experience: flock -xn my.lock cmd
my.lock is a file, it can be any file, and you can create a new empty file
When flock obtains the lock, it will execute the following cmd

Test process:

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

Only when 1 returns, 2's ls will be successful

If a script needs to run for 30 minutes, you can set the script interval in Crontab to at least one hour to avoid conflicts. The worse situation is that the script may not complete during the execution cycle, and then the second script starts running again. How can I ensure that only one instance of the script is run? A useful method is to use lockf (lockf under FreeBSD 8.1, flock under CentOS 5.5) to check whether a file lock can be obtained before the script is executed to prevent script running conflicts.

lockf parameters are as follows

-k: Wait to obtain the file lock.

-s: silent, does not send any information, even if the file lock cannot be obtained.

-t seconds: Set the timeout to seconds. If the time is exceeded, it will automatically give up.

Before executing the following crontab scheduled task, you need to obtain the temporary file create.lock file lock. The content of the crontab scheduled task is as follows:

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)

If the first If the first instance does not finish running within 10 minutes, the second instance will not run. I used to solve this problem through Shell scripts, such as using a while...do loop, and then executing it in the background. But later I found that it is simpler to use flock or lockf method.

Attached is the usage of flock under linux:

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超标解决办法。

The above is the detailed content of Reasons why Linux crond does not execute. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn