LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Shell script to start another program, if not running. (https://www.linuxquestions.org/questions/linux-software-2/shell-script-to-start-another-program-if-not-running-625589/)

cooljai 03-04-2008 05:09 AM

Shell script to start another program, if not running.
 
Hi,

I want a shell script which check whether a certain program is running or not, if not, then start it. There are two programs for which I need this. I have made this script and setup it in cron to execute it every hour for checking/starting of my programs:
first program name: logsUpdate.pl
Second program name: ProcessFetched.pl

Code:

#!/bin/bash

`ps ax | grep "[l]ogsUpdate.pl" > tmpCheckMgr`

if [ ! -s tmpCheckMgr ]
then
`/root/logsUpdate.pl` &
fi

`ps ax | grep "[P]rocessFetched" > tmpCheckLog`

if [ ! -s tmpCheckLog ]
then
`/root/ProcessFetched.pl now` &
fi

This script is working fine. It start the programs if they are not running but the problem is that it itself remain in memory (I can see it in ps list). I just want that this script will execute the programs and exit.

you may wonder why I'm using ps...> file to check program in process list. I also tested using if [`ps ax | grep ...` ], but it didnt came with desired result, that's why I've used this unusual code.

Can anybody please point me to right direction?

Thanks

chrism01 03-04-2008 05:34 AM

A few comments:

1. Instead of temp files, use a var eg:

log_found=`ps -ef|grep -v grep|grep gnome-terminal|awk '{print $8}'`

using grep -v grep to avoid picking up the grep process itself

2. backquotes redundant here

`/root/logsUpdate.pl` &

3. to detach from the process, use nohup eg:

nohup /root/logsUpdate.pl &

cooljai 03-04-2008 07:28 AM

Thanks very much Chris!

The code is really cool now.

marozsas 03-04-2008 07:35 AM

May be you can make the things a bit simpler.

Start yours programs as cronjobs, as usual, as recurrent jobs (i mean, every n minutes/hours it is up to you). This solves the problem they are not running. There is no need to check, just put it to run again every n minutes.

To avoid 2 or more instances of the same program running at the same time, use a lock.
Change your programs to add at the very beginning, something like that:

Code:

#!/bin/bash

unalias -a
trap onexit SIGINT SIGSEGV SIGQUIT SIGTERM

prog="yourprogramname"
lock="/tmp/${prog}.lock"

onexit () {
        rm -f "${lock}"
        exit
}

# check if the lock file is in place.
if [ -f $lock ]; then
        # silent exit is better from cron jobs,
        # echo "$0 Error: Lock file $lock is in place."
        # echo "Make sure an old instance of this program is not running, remove i
t and try again."
        exit
fi
date > $lock

#
# your script goes here
#
 
#
# exit your program calling onexit
#

onexit

In this way, if another instance is already running when the second one try to start, the check in the beginning will terminate the second instance, avoid 2 or more programs at the same time. When the first one ends, it removes the lock and another one can start.

The programs are independent and each one has its own lock.

cooljai 03-04-2008 11:40 PM

Thanks buddy for your valuable input.
.
As I need to run my scripts periodically but one of them is 'closed' source compiled script which, of course, I can not change. But it seems the script exit itself automatically when its instance already running.
.
The second script is in perl. I can modify it to suit the setting. Can you suggest a perl approach equivalent to your description above in shell script, means how to implement that "trap..." stuff in perl? or should I just go ahead with:
1) check lock when perl script starts, exit if lock is there.
2) if lock not there, create the lock file and continue.

That seems okay, but I'm a bit confused as what happened when my script get terminated in middle? (I can terminate it or system can restart), So plz advise in this regard.

Regards,

chrism01 03-05-2008 12:13 AM

Y, that lockfile stuff is broken if the prog terminates in the middle. If I need to do that (equiv) I either parse eg a 'ps -ef|grep -v grep|grep progname' cmd (see IPC::Open2 for example) or, even easier if the schedule is regular-ish, consider making a daemon of the job and just wait x seconds between loops, instead of cronning it.
You can also add a small watchdog shell script in cron in case the daemon fails.
Just depends on how critical the job is and whether you'd notice anyway if it failed, through other means eg no files appearing somewhere.

marozsas 03-05-2008 05:34 AM

Hi !

I think you could use the script I suggest as is, without modifying your scripts.
Just call your original script bellow "your script goes here". When your script ends for any reason, the call to "onexit" still is evaluated, no matter what language your original program is written.

Code:

...
#
# your script goes here
#

/root/logsUpdate.pl

#
# exit your program calling onexit
#

onexit

This is a kind of wrapper that make your original program aware of simultaneous execution.

But you really need to try. May be there are others factors we aren't seeing right now that could mess with.

And as chrism01 suggested, this is not the only solution. chrism01's hint is just as good as mine. You just need to choose one that best fit to the problem and to your style of doing things.

marozsas 03-05-2008 06:54 AM

Quote:

Originally Posted by cooljai (Post 3078504)
That seems okay, but I'm a bit confused as what happened when my script get terminated in middle? (I can terminate it or system can restart), So plz advise in this regard.

Regards,

I'm sorry I forget to comment this in my previous post.

Using the wrapper your script can terminate in the middle, doesn't matter.

If your system restart in the middle, problems may arise if your system does not clean /tmp at reboot (in some system this is configurable). The lock file is in place and the next run of wrapper is blocked.

To just remove lock files at reboot, you can add the following to the root's crontab:
Code:

#min    #hour  #day    #month  #week  #command
#0-59  0-23    1-31    1-12    0-7 (0,7=Sun, names are ok)
@reboot                                rm -f /tmp/*.lock


cooljai 03-05-2008 11:17 PM

Thanks again buddy for your cool suggestion. I'll test this stuff.

Btw, I did a naughty thing. I have tested that my closed source script will exit itself if its already running. thats good. Now to avoid running my own perl script twice, I am using this code in start of script:
Code:

my $CheckRun = `ps -ef|grep -v grep|grep logsUpdate.pl|wc -l`;
if($CheckRun > 1) {
#        print "\n Already running.";
        exit;
}

I think (plz correct me if I'm wrong) that I can achieve the desired without going other bigger possible ways (like making it daemon etc.)

I have entry in Cron to start it periodically and dropped that shell script for checking and starting. Everything seems good.

Regards,

ramslinux 07-20-2011 02:45 AM

Database is running or not if it is running then it will mount filesystem
 
Hi,

can you please tell me how to write these scripts

1. i need to check whether the database is running or not if it is running it will run auto mount script.

2. For every 1 hour i need to check mount partion is mounted or not if it is not mounted it should be mounted.

Thanks & Regards
Ram

chrism01 07-20-2011 06:56 PM

Do Not resurrect a 3 yr old thr. Please start a new one instead and supply my more detail eg distro+version, what DB etc.

rednectar 02-24-2012 05:28 AM

Thanks for nohup
 
Thanks for the tip Chris - might be an old thread but it still works ;) Was bashing my head (no pun intended) until you showed me "nohup"

chrism01 02-24-2012 05:44 AM

No worries: using '&' without nohup is a classic error in these sorts of situations.
'&' CAN be used without nohup, but usually only when the parent is waiting on/checking the child and is anyway already 'nohup'ped at some higher level.

vtudorache 03-13-2012 04:39 AM

More simple
 
You can use:

ps -C program_name | grep program_name

Good luck!


All times are GMT -5. The time now is 10:56 PM.