>  기사  >  운영 및 유지보수  >  Linux crond가 실행되지 않는 이유

Linux crond가 실행되지 않는 이유

小云云
小云云원래의
2018-03-20 14:04:552808검색

Linux 시스템의 CPU 사용량, 메모리 사용량, 로드를 정기적으로 모니터링하기 위해 Linux Shell 스크립트를 작성했습니다. 특정 값에 도달하면 정기적으로 이메일 알림이 전송됩니다. 그런데 crond에 이메일 알림을 보내기 위한 스크립트를 주기적으로 실행해달라고 요청했더니 crontab -e에 실행 스크립트를 추가했는데 스크립트가 실행되지 않는 것을 발견했습니다.

그러나 수동으로 스크립트를 실행하면 기본적으로 Linux 환경 변수를 얻을 수 있지만 Crontab에서 수행하는 예약된 작업을 통해 환경 변수인 Shell 스크립트 명령(./mimvp-email.sh)을 수동으로 실행하는 것이 일반적입니다. 얻을 수 없습니다.

이유를 분석해 보면 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 서비스의 기능을 수행할 수 없는 사용자를 제어하는 ​​데 사용됩니다.

파일에서 자신을 삭제하거나 루트에 문의할 수 있습니다

3. Crontab은 실행된 사용자의 환경 변수를 제공하지 않습니다.

해결책: 스크립트에 다음 줄을 추가합니다:

. /.bash_profile

4. 절대 경로가 사용되지 않습니다

여기서 절대 경로에는 스크립트의 경로와 crond 명령의 경로가 모두 포함됩니다(예:

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

5. 위 방법으로 문제가 해결되지 않으면 문제를 다시 찾아보세요.

1) 이 과정에서 사용자는 다음과 같은 이메일을 받게 됩니다.

vim /var/spool/mail/root

/var/spool/mail/root에 메일이 있습니다

가서 안에 있는 크론드 내용을 살펴보세요

파일이 너무 커서 열 수 없습니다. 가로챌 수 있습니다. 볼 수 있는 마지막 1000줄

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

2) 디버깅을 위해 스크립트에 출력 추가

echo를 추가할 수 있습니다. crontab 스크립트의 $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

루트 사용 다시 시작하면 문제가 해결됩니다:

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에서 스크립트 간격을 최소 1시간으로 설정할 수 있습니다. 더 나쁜 상황은 실행 주기 동안 스크립트가 완료되지 않고 두 번째 스크립트가 다시 실행되기 시작한다는 것입니다. 스크립트 인스턴스가 하나만 실행되도록 하려면 어떻게 해야 합니까? 유용한 방법은 스크립트 실행 충돌을 방지하기 위해 스크립트가 실행되기 전에 lockf(FreeBSD 8.1에서는 lockf, CentOS 5.5에서는 무리)를 사용하여 파일 잠금을 얻을 수 있는지 확인하는 것입니다.

lockf 매개변수는 다음과 같습니다.

-k: 파일 잠금을 얻을 때까지 기다립니다.

-s: 자동, 파일 잠금을 얻을 수 없는 경우에도 어떠한 정보도 보내지 않습니다.

-t초: 시간 초과를 초로 설정하면 자동으로 포기됩니다.

다음 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분 이내에 실행되면 두 번째 인스턴스 인스턴스가 실행되지 않습니다. 나는 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으로 문의하세요.