我的服务器每天 0点都会执行一个脚本,主要功能就是把我的网站和数据库打包备份到 Google 云端硬盘。之前使用的是宝塔面板来定时执行脚本,现在不用宝塔面板使用的就是 cron。

cron 是一个非常强大的定时任务工具,它允许用户安排在特定时间执行命令或脚本。cron 通过一个叫做 crontab 的配置文件来运行,每个用户都可以有自己的 crontab 文件来安排任务。

安装 cron

有的 Linux 可能已经内置了 cron,有的需要自己安装。

在 CentOS 检查是否安装了 cron:

rpm -q cronie

如果输出 cronie-1.4.11-25.el7_9.x86_64 之类的就是已安装。

如果没有安装的话,可以使用 yum 安装:

yum install cronie

在 Ubuntu 或 Debian 上查看是否安装 cron:

dpkg -l cron

如果看到 ii cron 3.0pl1-128ubuntu2 amd64 process scheduling daemon 之类的就是已安装。

如果没有安装的话,可以使用 apt 安装:

apt-get install cron

添加任务

添加任务需要通过 crontab 文件添加,下面打开 crontab 文件:

crontab -e

系统会使用默认的编辑器来打开 crontab 文件,你可以按照行来添加任务,任务的格式如下:

分钟 小时 天 月 星期 命令

下面添加一个任务,每个小时的 3 分执行 ping -c1 misterma.com

3 * * * * ping -c1 misterma.com

格式说明:

  • 3 把分钟设置为 3,也就是每个小时的 3 分执行
  • * 把小时设置为 *,也就是每小时都执行
  • * 把天设置为 *,也就是每天都执行
  • * 把月设置为 *,也就是每个月都执行
  • * 把星期设置为 *,也就是每个星期都执行

如果你需要每天的 0 点执行,格式就是这样:

0 0 * * * 命令

如果你需要每隔 10 分钟执行就是这样:

*/10 * * * * 命令

每隔 5 分钟执行:

*/5 * * * * 命令

每分钟执行一次:

* * * * * 命令

设置完成后可以查看 cron 服务是否在运行:

systemctl status crond

如果看到类似于下面的提示就说明正在运行:

● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2024-05-14 00:24:39 CST; 2 weeks 5 days ago
 Main PID: 511 (crond)
   CGroup: /system.slice/crond.service
           └─511 /usr/sbin/crond -n

如果没有运行可以启动 cron:

systemctl start crond
systemctl enable crond

如果你需要获取 cron 的执行结果可以查看 cron 的执行日志:

tail -f /var/log/cron

cron 日志会记录时间和执行的命令:

Jun  2 16:01:01 ma CROND[24194]: (root) CMD (run-parts /etc/cron.hourly)
Jun  2 16:01:01 ma run-parts(/etc/cron.hourly)[24194]: starting 0anacron
Jun  2 16:01:01 ma run-parts(/etc/cron.hourly)[24203]: finished 0anacron
Jun  2 16:03:01 ma CROND[24210]: (root) CMD (ping -c1 misterma.com)
Jun  2 17:01:01 ma CROND[25203]: (root) CMD (run-parts /etc/cron.hourly)
Jun  2 17:01:01 ma run-parts(/etc/cron.hourly)[25203]: starting 0anacron
Jun  2 17:01:01 ma run-parts(/etc/cron.hourly)[25212]: finished 0anacron
Jun  2 17:03:01 ma CROND[25227]: (root) CMD (ping -c1 misterma.com)

我上面添加的每个小时 3 分执行 ping -c1 misterma.com 也可以看到。

删除任务

删除任务还是通过编辑 crontab 文件的方式删除,打开 crontab 文件:

crontab -e

你可以直接删除不需要执行的行,或者在不需要执行的行前面加入一个 # 来注释行,修改完成后保存退出。

如果你要删除当前用户的所有任务可以直接使用:

crontab -r

查看 cron 任务

查看当前用户的 cron 任务可以使用:

crontab -l

你也可以通过 crontab -e 打开 crontab 文件来查看任务。

如果要查看其他用户的任务可以使用:

crontab -u userName -l

其中的 userName 就是你要查看的用户名,下面查看 www 用户的任务:

crontab -u www -l

注意,需要 root 管理员才能查看其他用户的任务!

把命令行输出重定向到文件

cron 日志只会记录时间和执行的命令,不会记录命令行输出的内容,如果你需要查看执行结果可以把输出重定向到一个文件。

下面在每小时 30 分执行 ping -c2 misterma.com,把命令行输出保存到 /home/log.txt

30 * * * * ping -c2 misterma.com >> /home/log.txt 2>&1

其中的 30 * * * * 就是在每小时的 30 分执行,ping -c2 misterma.com 就是执行的命令,>> /home/log.txt 就是把命令行输出写入到 /home/log.txt2>&1 是把标准错误重定向到标准输出。

下面就是自动执行的日志:

--- misterma.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 50.490/50.538/50.586/0.048 ms
PING misterma.com (172.93.47.76) 56(84) bytes of data.
64 bytes from mount.usa.one-host.ca (172.93.47.76): icmp_seq=1 ttl=51 time=50.6 ms
64 bytes from mount.usa.one-host.ca (172.93.47.76): icmp_seq=2 ttl=51 time=58.2 ms

--- misterma.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 50.613/54.406/58.200/3.800 ms
PING misterma.com (172.93.47.76) 56(84) bytes of data.
64 bytes from mount.usa.one-host.ca (172.93.47.76): icmp_seq=1 ttl=51 time=57.8 ms
64 bytes from mount.usa.one-host.ca (172.93.47.76): icmp_seq=2 ttl=51 time=57.7 ms

执行了两次。