How to poll existence of a background script correctly
Solution 1
pidof
won't find scripts, since it only looks at the first part of the process name (argv[0]
).
You could use pidof -m
, but that will find any long_running_script.sh
, not just the one started by this script.
A better way is to use the $!
variable, which holds the PID of the most recent background job.
#!/bin/bash
long_running_script.sh &
pid=$!
while ps -p $pid >/dev/null
do
echo "."
sleep 1
done
Solution 2
In the case you don't want a blocking wait
i would tackle this problem with bash's builtin job-control feature. For only one forked and executed process it is really simple and my approach looks like this
#!/bin/sh
sleep 1 &
while jobs | grep -q "Running" ; do
echo -n "." # no trailing newline
sleep 0.1
done
echo
Solution 3
Use wait
instead :
#!/bin/sh
long_running_script.sh &
wait
echo "done"
Related videos on Youtube
SKi
Updated on September 18, 2022Comments
-
SKi almost 2 years
I have a problem with the following kind of script:
#!/bin/sh long_running_script.sh & while [ `pidof long_running_script.sh` ] do echo "." sleep 1 done
The sript will start a new script to background, and it should print dots until the backgroud script will exit. It works when CPU load is not high.
But, when there is high CPU load, it won't work: long_running_script.sh will start, but the 'parent' script will exit from while loop before the long_running_script.sh exits.
Seems that
pidof
is executed before the long_running_script.sh is really started (execved).What is the best way to solve this problem?
1 seconds sleep before the while statement didn't help. So I don't want to use any magic delays, because it may be unreliable.
-
SKi almost 12 yearsHmm, I have problem with this. Some reason I can not
grep
output ofjobs
: <br/> # jobs | grep R <br/> # jobs <br/> [3] + Running sleep 100 <br/> [2] - Running sleep 100 <br/> # <br/> -
user1146332 almost 12 yearsProbably you misinterpret the output. Of course you get a line like
[3] + Running sleep 100 [2] - Running sleep 100
prompted on stdout, since grep finds your search patternR
and prints the corresponding line. The important point is what grep returns. If you invokeecho $?
immediatly after grepping you should see0
which signals success. A1
would mean that grep didn't find anything. Have you tried my example on your system? -
Gilles 'SO- stop being evil' almost 12 years@User1 Depending on your shell, you might not be able to use
jobs
in a subshell (e.g. in the left-hand side of a pipejobs | …
or in a command substitution$(jobs)
). Bash supports it, but not dash. -
SKi almost 12 years@user1146332 : Yes I try your example in 2 host. It work in Fedora PC, but not in my embedded Linux box with bysybox /bin/sh.
-
SKi almost 12 yearsOk, that $! works. ps command of busybox does not have -p option. But I replaced 'ps -p' to 'kill -0'. Now it works. Thanks.
-
StampyCode over 9 years
pidof -x $0
finds instances of the currently running script.