尽管我的if
语句告诉它如果进程或端口已经存在则不要运行,但 bash cronjob 仍会继续创建新进程...
猫/等/crontab
*/1 * * * * root /opt/script.sh
还尝试过:
* * * * * /opt/script.sh
该脚本打开一个端口,因此我尝试检查端口号以lsof
确定脚本是否已执行。
#!/bin/bash
port='1234'
if ! lsof -i | grep -o $port; then
command ...
fi
但那不起作用,每 60 秒就会执行另一个 script.sh,并且不知何故有多个进程占用了端口 1234。所以我尝试使用ps
lsof 而不是。
#!/bin/bash
c=$(sudo ps aux | grep -o '[s]cript\.sh')
if [[ $c != 'script.sh' ]]; then
command ...
fi
但这也不起作用。这是怎么回事?也许我误解了 cronjobs 的工作原理,因为我无法弄清楚为什么 if 语句不起作用并阻止命令一次又一次地执行。
我使用的是 ubuntu 16.04,已完全更新。
答案1
增加工作岗位的不同方式容易引起混淆cron
。
如果您添加的作业crontab -e
没有user
列(该作业以当前用户身份运行),而中的条目/etc/crontab
必须有user
列。由于您的条目在中/etc/crontab
,因此您需要使用第一种格式(请注意,计划时间*
和*/1
是等效的)。
只要您使用正确的crontab
条目,您的脚本使用lsof
应该可以工作,尽管grep -q
会停止不必要的输出。请注意,lsof
需要以 方式运行root
才能获得完整列表。
您的脚本使用起来ps
比较麻烦:-
sudo
如果你以 身份运行,则不需要使用 ,root
否则将会失败,因为它需要提示输入密码;另外,ps
无论是否以 身份运行,都会生成相同的列表root
。- 如果中有多个匹配项
ps ... | grep ...
,则需要使用双引号来确保设置中的语法正确c
。 - 如果
c
为空或者有多个匹配项,则$c
在测试中需要双引号以确保语法正确。 - 如果
c
包含多个实例script.sh
,则测试将失败。
您可以使用与脚本中相同的技术来解决这些问题lsof
:-
if ! ps aux | grep -q '[s]cript\.sh'; then
command ...
fi
顺便说一句,我喜欢使用来[s]cript\.sh
停止grep
匹配本身。