14

I am writing a script, but there is something I need that I can't find a way to do it...

I need to make a command in background "command1 &" and then somewhere in the script I need to wait for it to finish before I do command2. Basically, I need this:

NOTE: each command runs in a specific directory! at the end of the while loop my command1 created 4 directory's, where in each one run the specific process so the total of process running are 4

a=1

while [$a -lt 4 ]

     . command1
   #Generates 1 Process  

     a= `export $a +1`
done

   #Wait until the 4 process end and then run the command2 

    . command2

I've seen something about a wait command with the pid process number, but that didn't work also.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
Joao Macau
  • 225
  • 1
  • 4
  • 11
  • Do you control command1? Can you modify it so that it returns the PIDs of the 4 processes? – terdon Apr 10 '14 at 15:18
  • Yes! i have that already :) – Joao Macau Apr 10 '14 at 15:21
  • I have updated my answer accordingly. Tell me if it matches your excpectations. – Laurent C. Apr 10 '14 at 15:28
  • This Q is related to this one: http://unix.stackexchange.com/questions/100801/can-i-somehow-add-a-prog2-to-an-already-running-prog1/100812#100812. The only difference is you need to get the PID from a backgrounded process. You can use the $! variable to get this, passing it to the wait command as I showed there. $! contains the last backgrounded PID, while $$ contains the last process run's PID. – slm Apr 10 '14 at 15:40
  • 3
    OK, now your script makes no sense at all. There are syntax errors and strangeness all around. Could you show us the actual script? Why are you sourcing commands? Why not just execute them? – terdon Apr 10 '14 at 18:22

3 Answers3

27

You can use the command wait PID to wait for a process to end.

You can also retrieve the PID of the last command with $!

In your case, something like this would work:

command1 & #run command1 in background
PID=$! #catch the last PID, here from command1
command2 #run command2 while command1 is running in background
wait $PID #wait for command1, in background, to end
command3 #execute once command1 ended

Following your edit, as you have multiple PIDs and you know them, you can do that:

command1 & #run command1 in background
PID1=xxxxx
PID2=yyyyy
PID3=xxyyy
PID4=yyxxx
command2 #run command2 while command1 is running in background
wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end
command3 #execute once command1 ended
trusktr
  • 4,165
  • Following your edit, if you know the PID created (xxxxx, yyyyy, xxyyy, yyxxx), you can use wait as well, with the list of PIDs to wait for (see man). If you d'ont know them, maybe you can gather them into command1 (what is command1? a script of your own?) – Laurent C. Apr 10 '14 at 15:25
  • Probably best to ensure they're grouped correctly in the first place. See my answer for an idea of how it might be done. – mikeserv Apr 10 '14 at 16:38
5

The cleanest way to do this would be to have your comamnd1 return the PIDs of the launched processes and using wait on each of them as suggested by @LaurentC's answer.

Another approach would be something like this:

## Create a log file
logfile=$(mktemp)

## Run your command and have it print into the log file
## when it's finsihed.
command1 && echo 1 > $logfile &

## Wait for it. The [ ! -s $logfile ] is true while the file is 
## empty. The -s means "check that the file is NOT empty" so ! -s
## means the opposite, check that the file IS empty. So, since
## the command above will print into the file as soon as it's finished
## this loop will run as long as  the previous command si runnning.
while [ ! -s $logfile ]; do sleep 1; done

## continue
command2
terdon
  • 242,166
0

If you use the following method, you might not need a special "wait for all processes" after the while loop. The loop will wait for the current command1 to complete before it cycles back to top. Please use care as with any advice. Notice, the only thing I did was add & wait $! to the end of your command1.

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
techraf
  • 5,941