我有一个部署脚本。它必须向用户添加一些内容crontab
(触发一个脚本来清理日志XXX天);但是,只能在首次部署期间或需要更新时执行此操作。
(我可以跑步xxx.py deploy env
或xxx.py update env
。)
所以我需要这样做:
检查我的 cronJob 是否已存在
如果我的 cronJob 尚不存在,则提交它; 如果命令的参数之一不同,
则更新我的 cronJob
我不知道如何在crontab
不使用crontab -e
或“手动”编辑crontab
文件的情况下添加/检查/删除某些内容(下载、重写、重新上传)。
PS:这是一个用户特定的 cronjob; “webadmin”将执行此操作,但他不应该用来sudo
执行此操作。
答案1
到目前为止我最好的主意
首先检查内容是否与其中应有的内容匹配,如果不匹配则仅更新:
if [[ $(crontab -l | egrep -v "^(#|$)" | grep -q 'some_command'; echo $?) == 1 ]]
then
set -f
echo $(crontab -l ; echo '* 1 * * * some_command') | crontab -
set +f
fi
但这变得足够复杂,需要围绕该 cron 任务构建一个单独的脚本。
其他想法
您可以通过 stdin 将字符串发送到 crontab (注意,这会清除任何以前的 crontab 条目):
echo "* 1 * * * some_command" | crontab -
这甚至应该可以通过 ssh 正常工作:
echo "* 1 * * * some_command" | ssh user@host "crontab -"
如果你想追加到文件中,你可以使用这个:
# on the machine itself
echo "$(echo '* 1 * * * some_command' ; crontab -l 2>&1)" | crontab -
# via ssh
echo "$(echo '* 1 * * * some_command' ; ssh user@host crontab -l 2>&1)" | ssh user@host "crontab -"
答案2
作为记录,我建议使用/etc/cron.d/
.只有 root 可以在此处写入文件,但条目可以配置为以任何用户身份运行(无需sudo
在运行时)。此示例定义了名为的任务,该任务将在每周日午夜以用户身份my_webadmin
执行:/usr/local/bin/tidy_logfiles
webadmin
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' >/etc/cron.d/my_webadmin
一个重要的部分是,它my_webadmin
对于您来说应该是唯一的(尽管对于运行来说不一定是唯一的),因为任何安装包也可以在此处写入文件,并且您希望避免冲突。有了这个唯一性约束,您可以my_webadmin
通过简单的覆盖进行更新,因为您知道它是“您的”并且不会包含任何其他人/任何东西的条目。
此外,通过这种方法,删除 cron 条目变得微不足道
rm -f /etc/cron.d/my_webadmin
可能超出了您的问题范围,但如果您可以远程访问 root 帐户(或通过sudo
),您甚至可以远程配置,
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' > ~/webadmin.cron
scp -p ~/webadmin.cron root@remote_host:/etc/cron.d/my_webadmin
或者,
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' |
ssh -q root@remote_host 'cat >/etc/cron.d/my_webadmin'
并删除配置,
ssh -nq root@remote_host rm -f /etc/cron.d/my_webadmin
scp
(请注意,在许多情况下,您无法为/命令提供 root 的密码,ssh
因为 root 帐户受到限制以防止基于密码的登录。相反,您需要设置公钥/私钥证书。此外,暗示本地帐户(无论什么)它是)将拥有对远程服务器的完全root访问权限。)
答案3
答案4
这是对什么的改编@phillip-zyan-k-lee-stockmann根据他的“迄今为止最好的想法”代码提供。
我对他(优秀且有用的片段)的更改基本上是:
- 正则表达式不仅适用于命令名称,还适用于包括时间字符串在内的整个条目。这样,即使其他条目中存在同名或重叠命名的命令,它也可以支持添加命令。 (它仍然不会在同一时间表上添加同一命令两次。)
- 一点日志记录
- 由于各种原因,我将我的改为(并命名)为每小时;很容易根据 crontab 语法将其调整回来
这是我所说的代码crontab-add-hourly.sh
:
#!/bin/bash
# PURPOSE:
# To allow simple, programmatic addition of commands/entries into the crontab (if not already present)
cmd=$1
entry="0 * * * * $cmd"
printf "we want to add this entry:\n$entry\n\n"
escapedEntry=$(printf '%s\n' "$entry" | sed 's:[][\/.^$*]:\\&:g') #from: https://unix.stackexchange.com/a/129063/320236
printf "but first we'll see if it's already in there using this regex pattern:\n$escapedEntry\n\n"
if [[ $(crontab -l | egrep -v '^(#|$)' | grep -q "$escapedEntry"; echo $?) == 1 ]] # from: https://unix.stackexchange.com/a/297377/320236
then
printf "all clear; pattern was not already present; adding command to crontab hourly:\n$cmd\n\n"
(crontab -l ; printf "$entry\n\n") | crontab -
else
printf "pattern already present; no action taken\n\n"
fi
示例用法和输出:
$ ./crontab-add-hourly.sh my-script.bash
we want to add this entry:
0 * * * * my-script.bash
but first we'll see if it's already in there using this regex pattern:
0 \* \* \* \* my-script\.bash
all clear; pattern was not already present; adding command to crontab hourly:
my-script.bash