2

I have a bash script that looks like this:

#!/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

I have saved this file as restart.sh and when I run it like ./restart.sh, it does what its supposed to (kills the libt process and restarts it). However, now I am trying to automate the process by using cron. So I made a cron job that I want to run every 6 hours that looks like this

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

When I run "crontab -l" I can see this print so I know it's been added properly. I should mention that the service does not have the ability to be restarted, (like "service ... restart") the process ID needs to be found, killed and then the start script needs to be ran.

I have found that this cronjob is not working, I'll log onto the box and I can tell by looking at the logs that no restart has occurred. What am I doing wrong? What can I do to troubleshoot?

Any advice would help, this is my first cron job :) Thanks!

2
  • Do you see entries in your syslog for when this cron job is supposed to run?
    – EEAA
    Mar 9, 2011 at 5:16
  • 1
    Output from cronjobs end up in mail. Check out your account in /var/spool/mail.
    – Mark
    Mar 9, 2011 at 5:38

4 Answers 4

1

As well as allowing the user to run /bin/kill and libt without a password you will probably need to add the visiblepw to the Defaults section of the sudoers file e.g.

Defaults     env_reset, visiblepw

and

#allow user to run kill with no password entry
user    ALL=NOPASSWD: /bin/kill, /home/ec2-user/libt/libt
2
  • Thank you for the response, Iain, do I need to remove the line that reads Defaults requiretty Mar 9, 2011 at 16:49
  • @Pete Herbert Penito: change requiretty to visiblepw.
    – user9517
    Mar 9, 2011 at 18:25
4

Presumably, your intent with these lines is to avoid matching the grep command in the output of ps:

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

You can't guarantee that the second line will be the one you want. You should eliminate grep by using a common trick:

ps faux | grep [l]ibt

by enclosing a character in square brackets, grep looks for "libt" but not the literal "[l]ibt" because it interprets characters in brackets as a list.

You should use $() for command substitution instead of backticks. They're more readable and easier to do nesting.

You can also get both the username and PID using one call to ps reducing the chances of a race condition, but you don't really need the username since you know it already. You should only need to know whether the process is running or not.

However, there are still opportunities for false positives. If you can, you should use pgrep and 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

Please see Process Management for more information.

1
  • Thank you for the information! Good to know in the future Mar 10, 2011 at 22:49
2

sudo won't work in a cron job; it wants to prompt for a password, since you aren't keeping its semaphore file active when you're logged out. Consider installing it in root's crontab instead of your own.

3
  • 3
    ...unless the NOPASSWD option is granted in /etc/sudoers.
    – EEAA
    Mar 9, 2011 at 5:36
  • True. It probably still checks for a controlling terminal even without that, though, so still won't behave as desired from cron.
    – geekosaur
    Mar 9, 2011 at 5:47
  • 2
    You can add visiblepw to the Defaults in sudoers to enable sudo to work where there is no tty.
    – user9517
    Mar 9, 2011 at 8:58
2

You should try replacing this whole thing with ps-watcher or Monit pretty easily. That would solve your crontab issues.

Alternately, it looks like geekosaur is probably on the right track. If you want to keep the existing script, rewrite it to run from the root crontab. If it needs to do something as a different user, then use sudo or su as root to that user. That should work around any sudo weirdness you might be experiencing.

My vote on this is definitely for monit.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .