Linux crond不执行的原因

酷芳酱_9971

酷芳酱_9971

2018-03-20

3458人浏览

原创

为了定时监控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超标解决办法。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

linux

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Tailwind CSS 响应式布局怎么写
Tailwind CSS 响应式布局怎么写

Tailwind CSS 响应式布局通常从移动端样式写起,再用 sm、md、lg 等前缀调整不同屏幕宽度下的网格、间距和导航。本专题整理断点配置、Grid 与 Flex 自适应布局及常见溢出问题,帮助你逐步完成多设备适配。

2026.11.03

0

19

Tailwind CSS 常用类名怎么记
Tailwind CSS 常用类名怎么记

Tailwind CSS 类名很多,先按布局、间距、文字、颜色和状态分组记忆,再通过官方文档检索具体写法。本专题结合类名排序、动态拼接失效、自定义实用类等问题,帮助你建立常用类名的速查方法。

2026.11.03

0

12

码上飞入口地址合集
码上飞入口地址合集

本专题汇总了码上飞(CodeFlying)的官方入口地址合集,涵盖官网主站及网页版在线使用入口,支持注册登录后直接在线体验零代码AI应用生成。同时整理了APP端下载渠道与小程序入口,助你快速访问平台,通过自然语言描述需求即可生成应用、小程序或网站。

2026.11.03

0

10

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

2026.11.02

20

14

Uvicorn使用教程
Uvicorn使用教程

本专题汇总了Uvicorn使用教程与启动运行指南,涵盖其作为Python ASGI服务器的定位与特点,以及命令行启动(uvicorn main:app --reload)、参数配置(host/port/workers)、程序内嵌运行与Gunicorn结合部署等核心用法。同时整理了热重载调试、日志配置与生产环境部署优化等技巧,助你快速掌握Uvicorn的运行与配置。

2026.11.02

20

17

Uvicorn安装配置教程
Uvicorn安装配置教程

本专题汇总了Uvicorn的安装配置教程与部署指南,涵盖通过pip安装Uvicorn、启动FastAPI/Starlette应用、开发模式热重载(--reload)及多进程工作模式配置等核心操作。同时整理了结合Gunicorn的生产部署方案、HTTPS与反向代理配置及性能调优技巧,助你快速完成Uvicorn服务的安装与上线部署。

2026.11.02

20

17

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

120

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

100

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

300

10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习