文章目录
- crontabl【循环定时任务】
- crontabl说明
- 参数说明
- 格式说明
- 使用示例
- 使用实例
- 脚本无法执行问题
- 官方解决方法
- crontabl执行报错解决办法
- crontab中expect脚本不能正常运行解决方案
- 定时任务执行sh脚本中含有的expect脚本方法
- 给crontab添加环境变量
- at【一次性定时任务】
- 说明
- 参数说明
- 实例
- 立即执行一个任务
- 指定时间执行一个任务
- 指定脚本执行一个任务
- 查看、列出任务详细、删除、发送email说明
crontabl【循环定时任务】
crontabl说明
-
Linux crontab 是 Linux 系统中用于设置周期性被执行的指令的命令。
-
当安装完成操作系统之后,默认便会启动此任务调度命令。
-
crond 命令每分钟会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。
注意:新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。 -
Linux 任务调度的工作主要分为以下两类:
- 1、系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
- 2、个人执行的工作:某个用户定期要做的工作,例如每隔 10 分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置
-
语法
- 方式一:
crontab [ -u user ] file
- 方式二:
crontab [ -u user ] { -l | -r | -e }
- 方式一:
-
补充说明:
-
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。
-
-u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。
-
参数说明
-
crontab参数说明:
-e
: 执行文字编辑器来设定时程表,内定的文字编辑器是 Vi/Vim,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)-r
: 删除目前的时程表-l
: 列出目前的时程表
-
示例:
- 查看当前用户的 crontab 文件:
crontab -l
- 编辑当前用户的 crontab 文件:
crontab -e
- 删除当前用户的 crontab 文件:
crontab -r
- 列出某个用户的 crontab 文件(需要有相应的权限):
crontab -u username -l
- 编辑某个用户的 crontab 文件(需要有相应的权限):
crontab -u username -e
- 查看当前用户的 crontab 文件:
格式说明
- 参数解析
f1 f2 f3 f4 f5 program
- 其中
- f1 是表示分钟
- f2 表示小时
- f3 表示一个月份中的第几日
- f4 表示月份
- f5 表示一个星期中的第几天
- program 表示要执行的程序。
- 当 f1 为
*
时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推 - 当 f1 为
a-b
时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为a-b
时表示从第 a 到第 b 小时都要执行,其余类推 - 当 f1 为
*/n
时表示每 n 分钟个时间间隔执行一次,f2 为*/n
表示每 n 小时个时间间隔执行一次,其余类推 - 当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,其余类推
- 其中
分 时 日 月 周
* * * * *
- - - - -
| | | | |
| | | | +----- 星期中星期几 (0 - 6) (星期天 为0)
| | | +---------- 月份 (1 - 12)
| | +--------------- 一个月中的第几天 (1 - 31)
| +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)
使用示例
使用者也可以将所有的设定先存放在文件中,用 crontab file 的方式来设定执行时间。
下面是一些常用组合
时间设置 | 含义 |
---|---|
* * * * * | 每分钟执行一次 |
0 * * * * | 每小时的第 0 分钟执行一次 |
0 0 * * * | 每天的午夜(0 点)执行一次 |
0 0 * * 0 | 每周日的午夜(0 点)执行一次 |
0 0 1 * * | 每个月的第一天午夜(0 点)执行一次 |
0 0 L * * | 每个月的最后一天午夜(0 点)执行一次,其中L在日期(天)的位置可能 “本月的最后一天” |
0 0 1 1 * | 每年的第一天午夜(0 点)执行一次 |
0 0 * * 3 | 每周三的午夜(0 点)执行一次 |
0 0 1,15 * * | 每个月的第 1 和第 15 天午夜(0 点)执行一次 |
0 0 * * FRI | 每周五的午夜(0 点)执行一次,其中FRI代表星期五(Friday) |
0 0 * * 5 | 每周五的午夜(0 点)执行一次 |
0 8-17 * * * | 每天的上午 8 点到下午 5 点每小时执行一次 |
0 12 * * MON | 每周一的中午(12 点)执行一次,其中MON:代表周一(Monday)。 |
0 0 15 * * | 每个月的第 15 天午夜(0 点)执行一次 |
0 0 * * 3 | 每周三的午夜(0 点)执行一次 |
0 8-17 * * * | 每天的上午 8 点到下午 5 点每小时执行一次 |
0 0 * * 1-5 | 每个工作日的午夜(0 点)执行一次 |
0 0 1 * FRI | 每个月的第一个星期五午夜(0 点)执行一次,其中FRI代表星期五(Friday) |
0 0 1,15 * * | 每个月的第 1 和第 15 天午夜(0 点)执行一次 |
0 0 15 1 * | 每年的 1 月 15 日午夜(0 点)执行一次 |
0 0 * * 7 | 每周日的午夜(0 点)执行一次 |
0 0 * * 5 | 每周五的午夜(0 点)执行一次 |
使用实例
* * * * * /bin/ls #每一分钟执行一次 /bin/ls
*
0 */2 * * * /sbin/service httpd restart #意思是每两个小时重启一次apache 50 7 * * * /sbin/service sshd start #意思是每天7:50开启ssh服务 50 22 * * * /sbin/service sshd stop #意思是每天22:50关闭ssh服务 0 0 1,15 * * fsck /home #每月1号和15号检查/home 磁盘 1 * * * * /home/bruce/backup #每小时的第一分执行 /home/bruce/backup这个文件 00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} \; #每周一至周五3点钟,在目录/home中,查找文件名为*.xxx的文件,并删除4天前的文件。30 6 */10 * * ls #意思是每月的1、11、21、31日是的6:30执行一次ls命令
- 注意:当程序在你所指定的时间执行后,系统会发一封邮件给当前的用户,显示该程序执行的内容,若是你不希望收到这样的邮件,请在每一行空一格之后加上
> /dev/null 2>&1
即可,如:
20 03 * * * /var/www/runboo/test.sh > /dev/null 2>&1
脚本无法执行问题
官方解决方法
-
如果我们使用 crontab 来定时执行脚本,无法执行,但是如果直接通过命令(如:./test.sh)又可以正常执行,这主要是因为无法读取环境变量的原因。
-
解决方法:
-
1、所有命令需要写成绝对路径形式,如: /usr/local/bin/docker。
-
2、在 shell 脚本开头使用以下代码:
#!/bin/sh. /etc/profile . ~/.bash_profile
- 3、在 /etc/crontab 中添加环境变量,在可执行命令之前添加命令 . /etc/profile;/bin/sh,使得环境变量生效,例如:
20 03 * * * . /etc/profile;/bin/sh /var/www/runoob/test.sh
-
crontabl执行报错解决办法
- 有时候我们做合规,会导致定时任务就不能用。报错如下
[root@computer03 ~]# crontab -l
You (root) are not allowed to access to (crontab) because of pam configuration.
[root@computer03 ~]#
- 处理方法,可能是改pam文件出问题了
现在/etc/pam.d/crond的配置内容如下
[root@computer03 ~]# cat /etc/pam.d/crond
#
# The PAM configuration file for the cron daemon
#
#
# No PAM authentication called, auth modules not needed
account required pam_access.so
account include password-auth
session required pam_loginuid.so
session include password-auth
auth include password-auth
[root@computer03 ~]#
- 改为下面内容即可
[root@computer03 ~]# vi /etc/pam.d/crond
#
# The PAM configuration file for the cron daemon
#
#
# No PAM authentication called, auth modules not needed
#account required pam_access.so
#account include password-auth
#session required pam_loginuid.so
#session include password-auth
#auth include password-auth
account sufficient pam_access.so
account include system-auth
session sufficient pam_loginuid.so
session include system-auth
auth sufficient pam_rootok.so
auth required pam_env.so
auth include system-auth
~
- 改完以后,定时任务就正常了
[root@computer03 ~]# crontab -l
* * * * * /usr/sbin/ntpdate controller01 > /dev/null 2>&1
[root@computer03 ~]#
- 上面改的代码解释
-
ccount sufficient pam_access.so
:指示在身份验证成功后,检查用户是否被允许访问系统。pam_access.so模块根据访问控制规则允许或拒绝用户访问。 -
account include system-auth
:包含system-auth文件的账户配置,system-auth文件通常包含一些通用的账户管理规则。 -
session sufficient pam_loginuid.so
:在用户会话开始时记录登录ID(loginuid)。这通常用于审计和跟踪用户活动。 -
session include system-auth
:包含system-auth文件的会话配置,system-auth文件包含一些通用的会话管理规则。 -
auth sufficient pam_rootok.so
:在用户以root身份运行命令时提供免密码的授权。当使用sudo或su命令切换至root用户时,pam_rootok.so模块允许授权而不需要密码。 -
auth required pam_env.so
:在用户身份验证期间读取和设置环境变量。pam_env.so模块用于在用户登录期间加载和设置环境变量。 -
auth include system-auth
:包含system-auth文件的身份验证配置,system-auth文件通常包含一些通用的身份验证规则。
-
crontab中expect脚本不能正常运行解决方案
crontab中expect脚本不能正常运行解决方案
定时任务执行sh脚本中含有的expect脚本方法
定时任务执行sh脚本中含有的expect脚本方法、定时任务执行expect脚本并将结果输出到文件的方法
给crontab添加环境变量
-
直接将你的环境变量添加到crontab中即可,
echo $PATH
可以查看你的环境变量,如下,默认变量PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-
例如,如果你的脚本位于 /home/user/scripts/ 目录下,你的 crontab 文件中的条目可能如下所示:
-
使用绝对路径:
在 cron 任务中,最好使用脚本的绝对路径,这样 cron 守护进程就能正确找到并执行脚本。0 1 * * * /home/user/scripts/your_script.sh #这行表示每天凌晨1点执行 /home/user/scripts/your_script.sh 脚本。
-
环境变量:【最好在环境变量中默认加上下面PATH环境变量内容,避免出错】
cron 任务在执行时不会加载用户的环境变量,除非你在 cron 任务中显式地定义它们。如果你的脚本依赖于特定的环境变量(例如 PATH 或其他自定义变量),你需要在 cron 任务中包含这些变量。
例如:PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0 1 * * * /home/user/scripts/your_script.sh
-
日志记录:
考虑在脚本中添加日志记录功能,以便跟踪 cron 任务的执行情况。你可以将日志输出到一个文件中,例如:* * * * * /home/user/scripts/your_script.sh >> /home/user/scripts/your_script.log 2>&1 #这会将标准输出和标准错误都重定向到日志文件。
at【一次性定时任务】
说明
- 简单来说at定时任务,指定一个时间执行一个任务,且只执行一次。
- 这个命令需要安装:
yum -y install at
然后启动服务systemctl restart atd
参数说明
-
一般需要用到的参数如下
-f
:指定包含具体指令的任务文件;-q
:指定新任务的队列名称;-l
:显示待执行任务的列表;也是atq的别名-c
:打印任务的内容到标准输出-d
:删除指定的待执行任务;-m
:任务执行完成后向用户发送E-mail。
-
时间格式
at HH:MM
#指定时间执行 如09:20
说明:在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此任务。at HH:MM YYYY-MM-DD
精确到年,应该没有这种场景哈,如10:20 20251212
说明:规定在某年某月的某一天的特殊时刻进行该项任务at now+*minutes
#*分钟后执行…at now+*hours
# *小时候执行…at 04:00am + 4days
#4天后上午4点执行…at 04:00pm +4weeks
#4周后下午4点执行…
实例
立即执行一个任务
- 立即执行一次性任务,使用
at now
命令,输入该命令后- 会在终端下面出现一个at>提示符,此时输入要执行的命令,输完后回车
- 然后按下Ctrl+D即可。
[root@node-3 ~]# at now
at> echo hello > /root/hello.txt
at> <EOT>
job 4 at Thu Dec 12 18:56:00 2024
[root@node-3 ~]#
[root@node-3 ~]# cat hello.txt
hello
[root@node-3 ~]#
指定时间执行一个任务
- 定义19:03执行某命令
[root@node-3 ~]# date
Thu Dec 12 19:01:01 CST 2024
[root@node-3 ~]# at 19:03
at> echo hello >> /root/hello.txt
at> <EOT>
job 5 at Thu Dec 12 19:03:00 2024
[root@node-3 ~]#
[root@node-3 ~]# at -l
5 Thu Dec 12 19:03:00 2024 a root
[root@node-3 ~]# atq
5 Thu Dec 12 19:03:00 2024 a root
[root@node-3 ~]#
You have new mail in /var/spool/mail/root
[root@node-3 ~]#
[root@node-3 ~]# cat hello.txt
hello
hello
[root@node-3 ~]#
- 2分钟后执行一个脚本
[root@node-3 ~]# cat hello.sh
echo hello >> /root/hello.txt
date >> /root/hello.txt
echo _____________ >> /root/hello.txt
[root@node-3 ~]#
[root@node-3 ~]# date
Thu Dec 12 19:08:28 CST 2024
[root@node-3 ~]# at now + 2minutes
at> sh hello.sh
at> <EOT>
job 8 at Thu Dec 12 19:10:00 2024
[root@node-3 ~]# atq
8 Thu Dec 12 19:10:00 2024 a root
[root@node-3 ~]# > hello.txt
[root@node-3 ~]# date
Thu Dec 12 19:09:30 CST 2024
[root@node-3 ~]# date
Thu Dec 12 19:10:02 CST 2024
[root@node-3 ~]#
# 定时任务没内容就表示已经执行了
[root@node-3 ~]# atq
[root@node-3 ~]#
[root@node-3 ~]# cat hello.txt
hello
Thu Dec 12 19:10:00 CST 2024
_____________
[root@node-3 ~]#
指定脚本执行一个任务
- at -f 后面跟脚本 和时间
如:at -f hello.sh 19:14
[root@node-3 ~]# cat hello.sh
echo hello >> /root/hello.txt
date >> /root/hello.txt
echo _____________ >> /root/hello.txt
[root@node-3 ~]#
[root@node-3 ~]# date
Thu Dec 12 19:12:50 CST 2024
[root@node-3 ~]# at -f hello.sh 19:14
job 9 at Thu Dec 12 19:14:00 2024
[root@node-3 ~]# atq
9 Thu Dec 12 19:14:00 2024 a root
[root@node-3 ~]# atq
9 Thu Dec 12 19:14:00 2024 a root
[root@node-3 ~]# date
Thu Dec 12 19:13:30 CST 2024
[root@node-3 ~]# atq
[root@node-3 ~]# cat hello.txt
hello
Thu Dec 12 19:14:00 CST 2024
_____________
[root@node-3 ~]#
查看、列出任务详细、删除、发送email说明
- 我现创建一个任务出来
[root@node-3 ~]# at -f hello.sh 19:1^C
[root@node-3 ~]# date
Thu Dec 12 19:26:41 CST 2024
[root@node-3 ~]#
[root@node-3 ~]# at -f hello.sh 19:30
job 10 at Thu Dec 12 19:30:00 2024
[root@node-3 ~]#
- 查看任务
atq和at
-l均可以
[root@node-3 ~]# atq
10 Thu Dec 12 19:30:00 2024 a root
[root@node-3 ~]#
[root@node-3 ~]# at -l
10 Thu Dec 12 19:30:00 2024 a root
[root@node-3 ~]#
- 列出任务详细
at -c 任务序号
[root@node-3 ~]# at -l
10 Thu Dec 12 19:30:00 2024 a root
[root@node-3 ~]#
[root@node-3 ~]# at -c 10
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
umask 22
XDG_SESSION_ID=16; export XDG_SESSION_ID
HOSTNAME=node-3; export HOSTNAME
SELINUX_ROLE_REQUESTED=; export SELINUX_ROLE_REQUESTED
SHELL=/bin/bash; export SHELL
HISTSIZE=1000; export HISTSIZE
SSH_CLIENT=192.168.59.1\ 51434\ 22; export SSH_CLIENT
SELINUX_USE_CURRENT_RANGE=; export SELINUX_USE_CURRENT_RANGE
SSH_TTY=/dev/pts/0; export SSH_TTY
USER=root; export USER
LS_COLORS=rs=0:di=01\;34:ln=01\;36:mh=00:pi=40\;33:so=01\;35:do=01\;35:bd=40\;33\;01:cd=40\;33\;01:or=40\;31\;01:mi=01\;05\;37\;41:su=37\;41:sg=30\;43:ca=30\;41:tw=30\;42:ow=34\;42:st=37\;44:ex=01\;32:\*.tar=01\;31:\*.tgz=01\;31:\*.arc=01\;31:\*.arj=01\;31:\*.taz=01\;31:\*.lha=01\;31:\*.lz4=01\;31:\*.lzh=01\;31:\*.lzma=01\;31:\*.tlz=01\;31:\*.txz=01\;31:\*.tzo=01\;31:\*.t7z=01\;31:\*.zip=01\;31:\*.z=01\;31:\*.Z=01\;31:\*.dz=01\;31:\*.gz=01\;31:\*.lrz=01\;31:\*.lz=01\;31:\*.lzo=01\;31:\*.xz=01\;31:\*.bz2=01\;31:\*.bz=01\;31:\*.tbz=01\;31:\*.tbz2=01\;31:\*.tz=01\;31:\*.deb=01\;31:\*.rpm=01\;31:\*.jar=01\;31:\*.war=01\;31:\*.ear=01\;31:\*.sar=01\;31:\*.rar=01\;31:\*.alz=01\;31:\*.ace=01\;31:\*.zoo=01\;31:\*.cpio=01\;31:\*.7z=01\;31:\*.rz=01\;31:\*.cab=01\;31:\*.jpg=01\;35:\*.jpeg=01\;35:\*.gif=01\;35:\*.bmp=01\;35:\*.pbm=01\;35:\*.pgm=01\;35:\*.ppm=01\;35:\*.tga=01\;35:\*.xbm=01\;35:\*.xpm=01\;35:\*.tif=01\;35:\*.tiff=01\;35:\*.png=01\;35:\*.svg=01\;35:\*.svgz=01\;35:\*.mng=01\;35:\*.pcx=01\;35:\*.mov=01\;35:\*.mpg=01\;35:\*.mpeg=01\;35:\*.m2v=01\;35:\*.mkv=01\;35:\*.webm=01\;35:\*.ogm=01\;35:\*.mp4=01\;35:\*.m4v=01\;35:\*.mp4v=01\;35:\*.vob=01\;35:\*.qt=01\;35:\*.nuv=01\;35:\*.wmv=01\;35:\*.asf=01\;35:\*.rm=01\;35:\*.rmvb=01\;35:\*.flc=01\;35:\*.avi=01\;35:\*.fli=01\;35:\*.flv=01\;35:\*.gl=01\;35:\*.dl=01\;35:\*.xcf=01\;35:\*.xwd=01\;35:\*.yuv=01\;35:\*.cgm=01\;35:\*.emf=01\;35:\*.axv=01\;35:\*.anx=01\;35:\*.ogv=01\;35:\*.ogx=01\;35:\*.aac=01\;36:\*.au=01\;36:\*.flac=01\;36:\*.mid=01\;36:\*.midi=01\;36:\*.mka=01\;36:\*.mp3=01\;36:\*.mpc=01\;36:\*.ogg=01\;36:\*.ra=01\;36:\*.wav=01\;36:\*.axa=01\;36:\*.oga=01\;36:\*.spx=01\;36:\*.xspf=01\;36:; export LS_COLORS
MAIL=/var/spool/mail/root; export MAIL
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin; export PATH
PWD=/root; export PWD
LANG=en_US.UTF-8; export LANG
SELINUX_LEVEL_REQUESTED=; export SELINUX_LEVEL_REQUESTED
HISTCONTROL=ignoredups; export HISTCONTROL
SHLVL=1; export SHLVL
HOME=/root; export HOME
LOGNAME=root; export LOGNAME
SSH_CONNECTION=192.168.59.1\ 51434\ 192.168.59.143\ 22; export SSH_CONNECTION
LESSOPEN=\|\|/usr/bin/lesspipe.sh\ %s; export LESSOPEN
XDG_RUNTIME_DIR=/run/user/0; export XDG_RUNTIME_DIR
cd /root || {echo 'Execution directory inaccessible' >&2exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER63a07636'
echo hello > /root/hello.txt
date >> /root/hello.txt
echo _____________ >> /root/hello.txtmarcinDELIMITER63a07636
[root@node-3 ~]#
- 删除
at -d 任务序号
[root@node-3 ~]# at -l
10 Thu Dec 12 19:30:00 2024 a root
[root@node-3 ~]#
[root@node-3 ~]# at -d 10
[root@node-3 ~]# at -l
[root@node-3 ~]#
- 发送E-mail
就是任务执行完毕以后,会有个邮件通知如:You have new mail in /var/spool/mail/root
执行:at -m 执行条件
[root@node-3 ~]# at -m -f hello.sh 19:30
job 11 at Thu Dec 12 19:30:00 2024
[root@node-3 ~]# date
Thu Dec 12 19:29:28 CST 2024
[root@node-3 ~]# atq
You have new mail in /var/spool/mail/root
[root@node-3 ~]#
[root@node-3 ~]# cat hello.txt
hello
Thu Dec 12 19:30:00 CST 2024
_____________
[root@node-3 ~]#