28

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
  • 357
  • 1
  • 4
  • 8

6 Answers6

24

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

Edward Dale
  • 29,597
  • 13
  • 90
  • 129
  • Thanks. Could I use anything other than /var/run and /tmp like /home? – learner135 Jun 01 '10 at 07:34
  • 11
    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 Jun 03 '10 at 21:53
20

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
  • 29,501
  • 5
  • 55
  • 57
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
Chetan Gawai
  • 2,361
  • 1
  • 25
  • 36
4

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

4

$! 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
  • 16,005
  • 2
  • 34
  • 51
2

Code:

ps r

to report all running processes.

Helena
  • 31
  • 1
  • 1
    Could you elaborate more your answer adding a little more description about the solution you provide? – abarisone Mar 25 '15 at 10:08