我们正在为我们的应用程序服务器环境部署代码,并且该进程的一部分是在服务器上创建许多cron作业。当代码被推送时,我们的部署脚本使用以下内容创建所需的cron作业而没有问题:
CRON_FILE=$SCRIPT_DIR/cron.txt
if [[ ! -f "$CRON_FILE" ]]; then
printf "Cron template file missing!\n\n"
exit 1
fi
while read LINE || [[ -n "$LINE" ]]; do
printf "\n> Adding cron job \"$LINE\"\n"
crontab -l | { cat; echo "$LINE"; } | crontab -
done < $CRON_FILE
问题是在初始部署之后,其他部署正在创建重复的cron作业。
有关如何检测cron作业是否已存在的任何指示?
答案 0 :(得分:5)
添加cron作业时,请添加带有唯一标签的评论。稍后您可以使用该唯一标签来确定是否存在cron作业,还可以“卸载”cron作业。
我一直这样做。我有一个可重复使用的脚本:
#!/bin/sh
#
# Usage:
# 1. Put this script somewhere in your project
# 2. Edit "$0".crontab file, it should look like this,
# but without the # in front of the lines
#0 * * * * stuff_you_want_to_do
#15 */5 * * * stuff_you_want_to_do
#* * 1,2 * * and_so_on
# 3. To install the crontab, simply run the script
# 4. To remove the crontab, run ./crontab.sh --remove
#
cd $(dirname "$0")
test "$1" = --remove && mode=remove || mode=add
cron_unique_label="# $PWD"
crontab="$0".crontab
crontab_bak=$crontab.bak
test -f $crontab || cp $crontab.sample $crontab
crontab_exists() {
crontab -l 2>/dev/null | grep -x "$cron_unique_label" >/dev/null 2>/dev/null
}
# if crontab is executable
if type crontab >/dev/null 2>/dev/null; then
if test $mode = add; then
if ! crontab_exists; then
crontab -l > $crontab_bak
echo 'Appending to crontab:'
cat $crontab
crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo; } | crontab -
else
echo 'Crontab entry already exists, skipping ...'
echo
fi
echo "To remove previously added crontab entry, run: $0 --remove"
echo
elif test $mode = remove; then
if crontab_exists; then
echo Removing crontab entry ...
crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^\$/ d" | crontab -
else
echo Crontab entry does not exist, nothing to do.
fi
fi
fi
将脚本保存为项目目录中的crontab.sh
,并使用您的cron作业定义创建crontab.sh.crontab
,例如:
0 0 * * * echo hello world
0 0 * * * date
./crontab.sh
./crontab.sh --remove
我也把它放在GitHub上:https://github.com/janosgyerik/crontab-script
sed -e "\?^$cron_unique_label\$?,/^\$/ d"
的解释:
sed -e '/start/,/end/ d'
sed
命令,因为它需要扩展$cron_unique_label
shell变量的值\?^$cron_unique_label\$?
使用一对?
代替/
来封闭模式,因为$cron_unique_label
包含/
,这会导致问题< / LI>
?
进行转义,但说实话我不知道原因。^
匹配行的开头和行的$
结尾,$
必须转义,否则shell会扩展$?
的值shell变量/^\$/
相对简单,它匹配行的开头,后跟行尾,换句话说是空行,并且$
必须再次转义d
是sed
命令,用于删除匹配的行,有效地将其从crontab -l
的内容中删除,我们可以将其导入crontab -
答案 1 :(得分:1)
奇怪但非常彻底的答案。 IMO过于复杂。
对于2017年回答的人来说,这是一个不错的选择:
crontab -l | grep 'match-your-cronjob-search' || (crontab -l 2>/dev/null; echo "* * * * * /bin/cronjobCommandYouWant >> /dev/null 2>&1") | crontab -
非常适合我们没有笨蛋。
这是原始海报中编辑过的脚本:
CRON_FILE=$SCRIPT_DIR/cron.txt
if [[ ! -f "$CRON_FILE" ]]; then
printf "Cron template file missing!\n\n"
exit 1
fi
while read LINE || [[ -n "$LINE" ]]; do
printf "\n> Adding cron job \"$LINE\"\n"
crontab -l | grep "$LINE" || (crontab -l 2>/dev/null; echo "$LINE") | crontab -
done < $CRON_FILE
答案 2 :(得分:0)
你的脚本janos很棒,效果很好,正是我正在寻找的一个小故障。 我无法管理多个xxx.crontab模板。 你的脚本工作正常,我把它添加到我的bootstrapping例程稍加修改,所以我可以传递xx.crontab文件名的第一个参数$ 1和第二个参数$ 2可以删除。 我有父shell脚本,然后条件决定,我想要添加/删除的crontab文件的全部或组合。
这里包含我修改的脚本:
#!/bin/sh
#
# Usage:
# 1. Put this script somewhere in your project
# 2. Edit "$1".crontab file, it should look like this,
# but without the # in front of the lines
#0 * * * * stuff_you_want_to_do
#15 */5 * * * stuff_you_want_to_do
#* * 1,2 * * and_so_on
# 3. To install the crontab, run ./crontab.sh <nameOfCronTabfile>
# 4. To remove the crontab, run ./crontab.sh <nameOfCronTabfile> --remove
cd $(dirname "$0")
test "$2" = --remove && mode=remove || mode=add
cron_unique_label="# cmID:$PWD|$1#"
crontab="$1".crontab
crontab_bak=$crontab.bak
test -f $crontab || cp $crontab.sample $crontab
crontab_exists() {
crontab -l 2>/dev/null | grep -x "$cron_unique_label" >/dev/null 2>/dev/null
}
# if crontab is executable
if type crontab >/dev/null 2>/dev/null; then
if test $mode = add; then
if ! crontab_exists; then
crontab -l > $crontab_bak
echo 'Appending to crontab:'
echo '-----------------------------------------------'
cat $crontab
crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo "# cm #"; } | crontab -
else
echo 'Crontab entry already exists, skipping ...'
echo
fi
echo '-----------------------------------------------'
echo "To remove previously added crontab entry, run: $0 $1 --remove"
echo
elif test $mode = remove; then
if crontab_exists; then
echo 'Removing crontab entry ...'
crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^# cm #\$/ d" | crontab -
else
echo 'Crontab entry does not exist, nothing to do.'
fi
fi
fi
<强>更新强> Sry,没有注意到用于删除crontab的弱空行模式。只需在找到的crontab id之后删除所有内容,包括手动添加的crontabs。 将空行结束模式更改为小结束标记。 所以它会添加crontabs:
crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo "# cm #"; } | crontab -
..并且只删除了这个cron:
crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^# cm #\$/ d" | crontab -
答案 3 :(得分:0)
我们也可以用代码来做到这一点: 首先,请查看手册:man 2 open:
int fd = open('/tmp/1.txt', O_CREAT|O_EXCL)
if (fd === -1) {
print "job exist"
exit(1)
}
//unlink()
// your code
js版本:
const fs = require('fs')
try {
const fd = fs.openSync('/tmp/1.txt', 'wx')
} catch(err) {
console.log('job exist')
process.exit(0)
}
fs.unlinkSync('/tmp/1.txt')
fs.appendFileSync(fd, 'pid', 'utf8');