views:

301

answers:

3

I tried running a script using nohup like,

nohup script.sh &

When I tried

ps -ef | grep "script.sh"

I couldn't find it there except for the grep which is being run with that string as a parameter.

Am I doing it right?. Does this mean that the process has indeed finished execution? Thanks.

+3  A: 

At the beginning of your shell script, write the PID to a file (for example, in /var/run). Then, you can just search for that PID to know if the process is done or not. You can get the PID of your shell script using the built-in $$ variable.

To record the PID, put at the top of your script:

echo $$ > /var/run/myscript.pid

Then, to check if it's still running:

ps -p `cat /var/run/myscript.pid`

You might not be able to write into /var/run as a normal user. If not, just use /tmp

scompt.com
Thanks. Could I use anything other than /var/run and /tmp like /home?
learner135
Yup, whatever works best for you.
scompt.com
Note of caution: PIDs are sometimes re-used (more often on OSs without strong randomness, or on systems with lots of short-lived processes). The paranoid might want to check that the process has the right parent ($$), or have the child script remove the myscript.pid file on exit (something like ``trap "rm /var/run/myscript.pid EXIT''). Or both.
pra
+4  A: 

Subject to nohup implementation, but in most cases it will work. After running

nohup script.sh &

store the PID into a variable. $! is the PID of the last background process.

HISPID=$!

Then you can check if it's there with ps or kill:

ps -p $HISPID
kill -0 $HISPID

Unlike the other solution posted, this does not require modifying the script.sh

unbeli
Thanks but looks like $! is not supported in my shell environment. I am using ksh.
learner135
A: 

$! is definitely part of ksh and ksh93.

echo $SHELL

will show you what shell you're running.

Example of reasonable usage of &

#!/bin/ksh
nohup ./myscript.sh argument1 2>&1> mylogfile &
# do some other task
cnt=0
while [ $cnt -le 100 ]
do
    # work on another task here
    cnt=$(( $cnt + 1 ))
done
wait

The wait statement pauses for any still-running child process. Normally you don't plunk a process out into the background, expect it to run forever, and then completely forget it.

If you want a fully detached process that runs forever, consider a daemon. Some folks write daemons in shell - not best practice - but it is done. Normally UNIX daemons are written in C.

Chapter 13 of Stevens ' Advanced Programming in the UNIx Environment' 2ed is all about daemons.

jim mcnamara