0

bash cronjob continues to create a new process even though my if statement tells it not to run if the process or port already exists...

cat /etc/crontab

*/1 * * * * root /opt/script.sh

also tried:

* * * * * /opt/script.sh

the script opens a port so i tried checking port number using lsof to determine if the script was executed.

#!/bin/bash

port='1234'
if ! lsof -i | grep -o $port; then
    command ...
fi

but that didnt work, every 60 seconds another script.sh is executed and somehow there are multiple processes occupying port 1234. so i tried using ps instead of lsof.

#!/bin/bash

c=$(sudo ps aux | grep -o '[s]cript\.sh')
if [[ $c != 'script.sh' ]]; then
    command ...
fi

but that doesnt work either. whats going on here? maybe im misunderstanding how cronjobs work, because i cant figure out why the if statements arent working and preventing the command from executing again and again.

im using ubuntu 16.04, fully updated.

1

There is a confusion between different ways of adding cron jobs.

If you add a job with crontab -e there is no user column (the job is run as the current user), whereas entries in /etc/crontab must have the user column. Since your entries are in /etc/crontab, you need to use your first format (note that in the schedule time * and */1 are equivalent).

Provided that you are using the correct crontab entry, your script using lsof should work, although grep -q would stop unnecessary output. Note that lsof needs to be run as root in order to get a full list.

Your script using ps is more problematic:-

  • The use of sudo is unnecessary if you are running as root and will fail otherwise, as it needs to prompt for the password; also, ps produces the same listing whether running as root or not.
  • If there is more than one match in the ps ... | grep ..., then you need double quotes for correct syntax in setting c.
  • If c is empty or there is more than one match, then $c in the test will need double quotes for correct syntax.
  • If c contains more than one instance of script.sh, then the test will fail.

You could get round these problems by using the same technique as you used in the lsof script:-

if ! ps aux | grep -q '[s]cript\.sh'; then
    command ...
fi

By the way, I like the use of [s]cript\.sh to stop grep matching itself.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.