Only one instance of bash script...
I have an entry in my crontab as follows:
0,15,30,45 * * * * cd /home/user/seti; ./setitime.sh > /dev/null 2> /dev/null It is set to launch a script (setitime.sh) that logs the time it takes my machine to process seti@home packets. The script is as follows: #!/bin/bash # display the duration in a logical string duration () { totalsecs=$1 secs=$(($totalsecs % 60)) mins=$((($totalsecs % 3600) / 60)) hours=$(($totalsecs / 3600)) if [ $hours = 0 ] && [ $mins = 0 ] then result_str="$secs second(s)" elif [ $hours = 0 ] then result_str="$mins minutes(s) $secs second(s)" else result_str="$hours hour(s) $mins minute(s) $secs second(s)" fi echo $result_str } # clean up old files #rm -f time touch setitime echo "Seti packet started at `date`" >> setitime START_DATE=`date +%s` #Do some stuff ./setiathome -nice 1 -stop_after_process echo "Seti packet finished at `date`" >> setitime END_DATE=`date +%s` echo "Seti packet duration = `duration $(($END_DATE - $START_DATE))`" >> setitime echo "----------------------------------------" >> setitime echo "" >> setitime In normal operating mode multiple instances of setiathome will not run if an instance of setiathome is already running. Is there a way to prevent multiple instances of my script from running? The way I would like this to work is: - cron launches setitime.sh. - setitime.sh logs the start time to setitime, launhes setiathome (with the option to stop after processing) - setiathome stops processing, setitime.sh logs the stop time to setitime. - setitime.sh stops - cron launches setitime.sh - (repeat) If cron attemps to start a second instance of setitime.sh, it aborts. Here's what's happeneing: - cron launches setitime.sh. - setitime.sh logs the start time to setitime, launhes setiathome (with the option to stop after processing) - 15 minutes pass and cron launches a second setitime.sh - setitime.sh logs the start time to of the second seti@home to setitime. - can't run 2 setiathome. second instnace of setiathome aborts. - setitime.sh logs the stop time of 2nd setiathome to setitime. - setitime.sh logs the duration of 2nd instance of setiathome to setitime (0 seconds) - (repeat from step 3 every 15 minutes) Any thoughts on how to only allow 1 instance of my bash script? |
just check a ps output to see if it is already running
Code:
if [ `ps ax | grep -c setiathome` ] then |
OK...
i've played around with this for a ilttle while. what I really need is for the test to pass when it DOES NOT find an instance of itself already running. I've put this in a test script this works when setitime.sh is running. #!/bin/bash if [ `ps aux|grep -c setitime.sh` ]; then echo "setitime.sh running" fi I need something like #!/bin/bash if [ `ps aux|grep -c setitime.sh` -eq 0 ]; then echo "setitime.sh is not running" fi the above does not seem to work, nor have any variants I've tried. Any ideas anyone? |
you should ps against the actual seti program, not your script.
if [ ! `ps ax | grep setiathome` ] then or if [ `ps ax | grep -c setiathome` -eq 0 ] then thinking about it, that ps command itself may well be counted in the grep command, so it might well always be at least one, not 0... not sure. |
Tried both variations. Neither worked. I finally got this to do what I want:
#!/bin/bash foo=`ps aux | grep -c setiathome` #echo $foo if [ "$foo" -eq "0" ]; then echo "setitime.sh is not running" fi The beauty of Linux... more than one way to skin a cat. Thanks for your help. |
hmm, not really, that's just doing things the long way round.
|
Code:
printERROR() { |
Thought I'd have a go at it too.
Called from top of script, no args necessary. If you're on RH, "pidof" kinda equals pgrep. checkRun0() { if [ "$(pgrep -d "" -f $0)X" != \ "$(pgrep -d "" -f -n $0)X" ]; then exit 1; fi; } checkRun1() { procStr=( $(pgrep -d " " -f $0) ) case "${#procStr[@]}" in 1) continue;; 0|2|*) exit 1;; esac; } |
https://github.com/sayanarijit/pidlock
pidlock -n sleepy_script -c 'sleep 10'
|
@sayanarijit:
You have replied to a 15 year dead thread, and although your script may be relevant you did not provide any description of your solution other than a link and command example. If you wish to share your solution with current users please post to your own thread and provide relevant detail so that your post is complete and more useful to others. Please see the Site FAQ for guidance in posting and forum participation. And welcome to LQ! |
Code:
if [ `ps aux|grep -c setitime.sh` ]; then Correct is, in the grep argument enclose (at least) one character in [ ]. Then it still searches the bare character, but the [ ] will appear in the ps list and will not match. Because [ ] is special to the shell, the grep argument must be put in quotes. In this case there is another glitch: the . matches any character, and should be escaped \. or put in a character set [.]. Take the latter - it also solves the race condition! Last but not least, one can use the exit status, saves a subshell. Code:
if ps aux | grep -wq "setitime[.]sh"; then |
but nowadays you can use pgrep instead of ps | grep and that works quite well. Otherwise (in general) a lock file should be used in such cases.
|
All times are GMT -5. The time now is 10:03 AM. |