Cronjob未运行

Cronjob未运行

我有一个如下所示的 bash 脚本:

#!/bin/sh

PID=`ps faux | grep libt | awk 'NR==2{print $2}'`
STATUS=`ps faux | grep libt | awk 'NR==2{print $1}'`
if [ "$STATUS" = "ec2-user" ]; then
 echo "libt already killed"
else
 sudo kill $PID
 echo "libt was killed"
fi
sleep 5
cd /home/ec2-user/libt
sudo ./libt

我已将此文件保存为 restart.sh,当我像 ./restart.sh 一样运行它时,它会执行其应有的操作(终止 libt 进程并重新启动它)。但是,现在我正尝试使用 cron 来自动化该过程。因此,我创建了一个 cron 作业,希望每 6 小时运行一次,如下所示

0 */6 * * * /home/ec2-user/restart.sh

当我运行“crontab -l”时,我可以看到此打印,所以我知道它已被正确添加。我应该提到,该服务没有重新启动的能力,(如“service ... restart”)需要找到进程 ID,然后终止进程 ID,然后运行启动脚本。

我发现这个 cronjob 不起作用,我登录到机器上,通过查看日志可以发现没有发生重新启动。我做错了什么?我可以做什么来排除故障?

任何建议都会有帮助,这是我的第一个 cron 作业:) 谢谢!

答案1

除了允许用户运行/bin/killlibt无需密码之外,您可能还需要visiblepwDefaultssudoers文件例如

Defaults     env_reset, visiblepw

#allow user to run kill with no password entry
user    ALL=NOPASSWD: /bin/kill, /home/ec2-user/libt/libt

答案2

据推测,您使用这些行的目的是为了避免匹配grep输出中的命令ps

PID=`ps faux | grep libt | awk 'NR==2{print $2}'`
STATUS=`ps faux | grep libt | awk 'NR==2{print $1}'`

你不能保证第二行就是你想要的。你应该grep使用一个常用技巧来消除:

ps faux | grep [l]ibt

通过将字符括在方括号中,grep会查找“libt”而不是文字“[l]i​​bt”,因为它将括号中的字符解释为列表。

你应该用于$()命令替换而不是反引号。它们更易读,也更容易嵌套。

您还可以通过一次调用获取用户名和 PID,以ps减少出现竞争条件的可能性,但您实际上并不需要用户名,因为您已经知道了。您只需要知道该进程是否正在运行。

但是,仍然有误报的可能性。如果可以,您应该使用pgreppkill

#!/bin/sh
PID=$(pgrep -U ec2-user libt 2>/dev/null)
if [ $? = 0 ]
then
    kill $PID
    echo "libt was killed"
else
    echo "libt already killed"
fi
sleep 5
/home/ec2-user/libt/libt

请参见流程管理了解更多信息。

答案3

sudo在 cron 作业中不起作用;它会提示输入密码,因为您注销时不会保持其信号文件处于活动状态。考虑将其安装在 的rootcrontab 中,而不是您自己的 crontab 中。

答案4

你应该尝试用以下方法替换整个东西ps-观察者或者监控非常简单。这将解决您的 crontab 问题。

另外,geekosaur 似乎走在正确的轨道上。如果您想保留现有脚本,请将其重写为从 root crontab 运行。如果它需要以其他用户身份执行某些操作,则使用 sudo 或以 root 身份对该用户执行 su。这应该可以解决您可能遇到的任何 sudo 怪异问题。

对此我绝对支持 monit。

相关内容