我有一个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”,我可以看到这个打印,所以我知道它已被正确添加。 我应该提到,服务没有能力重新启动(如“服务…重新启动”)进程ID需要find,杀死,然后启动脚本需要运行。
我发现这个cronjob没有工作,我会login框,我可以通过查看没有重新启动的日志来告诉。 我究竟做错了什么? 我能做些什么来排除故障?
任何意见将有所帮助,这是我的第一个cron工作:)谢谢!
除了允许用户在没有密码的情况下运行/bin/kill和libt ,您可能还需要将visiblepw添加到sudoers文件的Defaults部分,例如
Defaults env_reset, visiblepw
和
#allow user to run kill with no password entry user ALL=NOPASSWD: /bin/kill, /home/ec2-user/libt/libt
据推测,你的意图与这些线路是为了避免匹配ps的输出中的grep命令:
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] ibt”,因为它将括号中的字符解释为列表。
您应该使用$()进行命令replace,而不是反引号。 他们更可读,更容易做嵌套。
您也可以通过一次调用ps来获得用户名和PID,从而减less竞争条件的机会,但是您并不需要用户名,因为您已经知道了。 您只需要知道该进程是否正在运行。
但是,仍然有误报的机会。 如果可以的话,你应该使用pgrep和pkill 。
#!/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
请参阅stream程pipe理了解更多信息。
sudo不会在cron工作中工作; 它希望提示input密码,因为注销时不会保持其信号文件处于活动状态。 考虑把它安装在root的crontab中,而不是你自己的。
你应该尽量用ps-watcher或Monit来replace这个东西。 这将解决您的crontab问题。
或者,看起来geekosaur可能是在正确的轨道上。 如果要保留现有脚本,请将其重写为从根crontab运行。 如果需要以不同的用户身份执行某些操作,则使用sudo或su作为该用户的root用户。 这应该可以解决你可能遇到的任何怪异问题。
我对这个投票肯定是monit。