Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question

3 Answers 3

up vote 4 down vote accepted

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
share|improve this answer
1  
Ok, that $! works. ps command of busybox does not have -p option. But I replaced 'ps -p' to 'kill -0'. Now it works. Thanks. –  User1 Sep 21 '12 at 6:43
    
pidof -x $0 finds instances of the currently running script. –  Stampy yesterday

Use wait instead :

#!/bin/sh
  long_running_script.sh &  
  wait
  echo "done"

More details.

share|improve this answer

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 
share|improve this answer
    
Hmm, I have problem with this. Some reason I can not grep output of jobs: <br/> # jobs | grep R <br/> # jobs <br/> [3] + Running sleep 100 <br/> [2] - Running sleep 100 <br/> # <br/> –  User1 Sep 20 '12 at 12:06
    
Probably 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 pattern R and prints the corresponding line. The important point is what grep returns. If you invoke echo $? immediatly after grepping you should see 0 which signals success. A 1 would mean that grep didn't find anything. Have you tried my example on your system? –  user1146332 Sep 20 '12 at 12:30
    
@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 pipe jobs | … or in a command substitution $(jobs)). Bash supports it, but not dash. –  Gilles Sep 21 '12 at 0:09
    
@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. –  User1 Sep 21 '12 at 6:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.