how to find whether a script run as a nohup finished or not?
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
Related videos on Youtube
learner135
Updated on July 09, 2022Comments
-
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 almost 14 yearsThanks but looks like $! is not supported in my shell environment. I am using ksh.
-
learner135 almost 14 yearsThanks. Could I use anything other than /var/run and /tmp like /home?
-
pra almost 14 yearsNote 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 about 9 yearsCould you elaborate more your answer adding a little more description about the solution you provide?