ubuntu crontab 定时执行 node 程序
2024-07-06 · 858 chars · 5 min read
之前一直没有用过 crontab,最近想要定时通过 rclone 备份一些文件,没想到踩到这么多坑:
- 默认情况下没有开日志
- crontab 里的 shell 是
sh
,环境变量不一样 - 时区问题,这个在 server 版的 ubuntu 上很容易遗漏
- 命令执行错误会发邮件,然而一般系统是没有配置邮件的,日志会显示
(CRON) info (No MTA installed, discarding output)
下面我把弯路捋直了,直接讲讲我现在的用法。另外,文后的参考链接挺有用的,建议看看。
安装#
先来安装 crontab 服务
sudo apt install cron
设置开机启动
sudo systemctl enable cron
一些其他命令
sudo systemctl restart crond.service # 重启服务 sudo systemctl status crond.service # 查看服务状态
开启日志#
默认情况下,crontab 的日志没有开启,执行
sudo vim /etc/rsyslog.d/50-default.conf
找到 cron.*
,把前面的注视 #
去掉,保存
# Default rules for rsyslog. # # For more information see rsyslog.conf(5) and /etc/rsyslog.conf # # First some standard log files. Log by facility. # auth,authpriv.* /var/log/auth.log *.*;auth,authpriv.none -/var/log/syslog cron.* /var/log/cron.log #daemon.* -/var/log/daemon.log kern.* -/var/log/kern.log
重启日志,重启 cron 服务
sudo systemctl restart rsyslog
sudo systemctl restart cron
之后就可以查看 cron 日志了
tail -f /var/log/cron.log
确认系统时区#
输入 timedatectl
命令查看:
Local time: Sat 2024-07-06 20:10:25 CST Universal time: Sat 2024-07-06 12:10:25 UTC RTC time: Sat 2024-07-06 12:10:24 Time zone: Asia/Shanghai (CST, +0800) System clock synchronized: yes NTP service: active RTC in local TZ: no
如果你的时区不是 Asia/Shanghai
的话,执行 sudo timedatectl set-timezone Asia/Shanghai
设置一下。
非东八区可以执行 timedatectl list-timezones
命令找找。
解决 node 执行问题#
相信大多数前端和我一样,不会直接安装 node,而是使用了类似 nvm 的版本管理工具。
这就带来一个问题,nvm 切换 node 版本的时候会修改环境变量,执行 echo $PATH
查 看:
/home/keenwon/.nvm/versions/node/v16.20.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
但是 crontab 的环境变量是不同的,所以直接用 node 命令 * * * * * node /path/index.js
会报错:
/bin/sh: 1: node: not found
我的解决办法是把 Nodejs 打包为一个可执行文件(Node.js SEA),可以查看这篇文章
配置定时任务#
最后,执行 crontab -e
即可为当前用户配置定时任务了,建议这么写
0 6 * * * /usr/bin/zsh -c "<你的 SEA 文件路径>" >/dev/null 2>&1
/usr/bin/zsh
可以换成你常用的 shell,避免麻烦。
>/dev/null 2>&1
是为了解决「邮件」问题,说明下:
/dev/null
是空设备文件,>/dev/null
的意思就是「什么都不输出」- 1 表示 stdout 标准输出
- 2 表示 stderr 标准错误
- & 表示「等同于」的意思
2>&1
表示 2 的输出重定向等同于 1(1 就是>/dev/null
,就是什么都不输出)
所以 >/dev/null 2>&1
的意思就是「什么都不输出」,也就不会发邮件了。
最后#
文章写出来就这么多,但是第一次使用,每一步都是坑,说多了都是泪...
crontab 感觉比较适合简单用,如果要执行很多复杂任务,推荐看看「青龙面板」,我在 docker 里安装试了下,功能挺强大的。但 docker 是一个隔离 的环境,不太符合我的需求,还是写点 node 代码比较简单。