我将制作一个在启动时执行并定期运行的 bash 脚本。
我希望它是用户可配置的,以便用户可以0 * * * * my_script
通过运行添加 cron 作业my_script add 0 * * * *
,列出作业my_script list
,并删除my_script remove job_number
作业编号在my_script list
命令输出中列出的位置。
如果我可以单独管理 crontab 文件,这将很容易实现。但是,似乎 crontab 每个用户只有一个文件(如果不是,请告诉我)。当然,直接处理那个 crontab 文件是一个糟糕的解决方案。
那么处理cron作业的正确方法是什么?或者,有没有更好的方法来处理定期运行的脚本?
状况:
补充问题:
由于我找不到任何适当的方法来管理定期运行的脚本,我想我可能做错了什么。在软件设计的意义上,实现接口来管理软件的定时任务是不是不切实际?我应该将所有日程管理留给用户吗?
使用 cron 是在大多数 Unix 系统上安排定期运行任务的正确方法。使用个人 crontab 是用户安排他们自己的任务的最方便的方式。系统任务可以由 root 调度(不使用下面的脚本!)在系统 crontab 中,它通常具有稍微不同的格式(带有用户名的额外字段)。
这是一个简单的脚本给你。任何用户都可以使用它来管理自己的个人 crontab。
它不会对其输入进行任何类型的验证,除了如果您给它的参数太少它会抱怨。因此,完全有可能添加格式不正确的 crontab 条目。
该remove
子命令采用行号,并将删除 crontab 中该行上的内容,而不管它是什么。该号码未经消毒,直接传递给sed
。
crontab 条目,当你添加一个时,必须被引用。这会影响您必须如何处理crontab 条目本身内的引号。
大多数这些事情对你来说应该相对容易解决。
#!/bin/sh
usage () {
cat <<USAGE_END
Usage:
$0 add "job-spec"
$0 list
$0 remove "job-spec-lineno"
USAGE_END
}
if [ -z "$1" ]; then
usage >&2
exit 1
fi
case "$1" in
add)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
tmpfile=$(mktemp)
crontab -l >"$tmpfile"
printf '%s\n' "$2" >>"$tmpfile"
crontab "$tmpfile" && rm -f "$tmpfile"
;;
list)
crontab -l | cat -n
;;
remove)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
tmpfile=$(mktemp)
crontab -l | sed -e "$2d" >"$tmpfile"
crontab "$tmpfile" && rm -f "$tmpfile"
;;
*)
usage >&2
exit 1
esac
Run Code Online (Sandbox Code Playgroud)
使用示例:
$ ./script
Usage:
./script add "job-spec"
./script list
./script remove "job-spec-lineno"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
$ ./script add "0 15 * * * echo 'hello world!'"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
4 0 15 * * * echo 'hello world!'
$ ./script remove 4
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
Run Code Online (Sandbox Code Playgroud)