how to find whether a script run as a nohup finished or not?

78,227

Solution 1

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

Solution 2

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

Solution 3

$! 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.

Solution 4

I followed the suggestion by scompt.com modifying my script to store the pid

Then I noticed the pid is written to the output, so there is no need to store it:

$ nohup ./sync-all.production.sh > sync-all.production.log &

[1] 3428

Solution 5

what has worked is

sudo ps -e | grep [script name or fragment of name]

for example for a script named "mf-sync.js"

sudo ps -e | grep mf-sync

displays the script name and the pid; then I can use, for example if pid was 1234

sudo kill 1234

next I need to add a timeout to automatically kill it after enough time has expired for it to run normally, but that is another question

meanwhile I can babysit this process to run the sync for my client, until I have time to test the timeout in a script

Share:
78,227

Related videos on Youtube

learner135
Author by

learner135

Updated on July 09, 2022

Comments

  • learner135
    learner135 almost 2 years

    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.

  • learner135
    learner135 almost 14 years
    Thanks but looks like $! is not supported in my shell environment. I am using ksh.
  • learner135
    learner135 almost 14 years
    Thanks. Could I use anything other than /var/run and /tmp like /home?
  • pra
    pra almost 14 years
    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.
  • abarisone
    abarisone about 9 years
    Could you elaborate more your answer adding a little more description about the solution you provide?