1

I have three shell scripts say A, B and C. I need to run A in the background and run B in the background till A finishes its execution in the background. Similarly run C in the foreground till A and B finish their execution.

I was doing this for 2 processes earlier in this way.

./A.sh &  
while ps -p $! >/dev/null; do   
./B.sh  
done 

I need to run B in background and C in foreground till A finishes its execution in background. How do I modify the above code.

3
  • I'm not quite clear, do you want B to wait to start until A is done? (that's what your current script does). Or do you want all of them running (A,B in background, C in foreground) and ... ? Wait to exit the script until they're all done? Or kill C once A and B are done? Commented Nov 23, 2011 at 2:20
  • Anyway, you should look into wait. Commented Nov 23, 2011 at 2:21
  • Kevin, I want all scripts to be running A,B in background and C in foreground. This loop has to break when A finishes its execution. Commented Nov 23, 2011 at 16:43

2 Answers 2

1

This will run A & B in the background with C in the foreground; B&C will loop until A finishes:

#!/bin/bash

./A.sh &
APID=$!

while ps -p ${APID} >/dev/null; do
    ./B.sh & ./C.sh
done

Example from my box:

[ 09:39 [email protected] ~/SO/bash ]$ cat A.sh
#!/bin/bash
echo "A Started at: `date`"
sleep 30
echo "A Finished at: `date`"

[ 09:39 [email protected] ~/SO/bash ]$ cat B.sh
#!/bin/bash
echo "B Started at: `date`"
sleep 10
echo "B Finished at: `date`"

[ 09:39 [email protected] ~/SO/bash ]$ cat C.sh
#!/bin/bash
echo "C Started at: `date`"
sleep 5
echo "C Finished at: `date`"

[ 09:38 [email protected] ~/SO/bash ]$ ./how-to-program-in-this-bash-script-of-background-processes.sh
A Started at: Wed Nov 23 09:38:39 PST 2011
C Started at: Wed Nov 23 09:38:39 PST 2011
B Started at: Wed Nov 23 09:38:39 PST 2011
C Finished at: Wed Nov 23 09:38:44 PST 2011
C Started at: Wed Nov 23 09:38:44 PST 2011
B Started at: Wed Nov 23 09:38:44 PST 2011
B Finished at: Wed Nov 23 09:38:49 PST 2011
C Finished at: Wed Nov 23 09:38:49 PST 2011
C Started at: Wed Nov 23 09:38:49 PST 2011
B Started at: Wed Nov 23 09:38:49 PST 2011
B Finished at: Wed Nov 23 09:38:54 PST 2011
C Finished at: Wed Nov 23 09:38:54 PST 2011
C Started at: Wed Nov 23 09:38:54 PST 2011
B Started at: Wed Nov 23 09:38:54 PST 2011
B Finished at: Wed Nov 23 09:38:59 PST 2011
C Finished at: Wed Nov 23 09:38:59 PST 2011
C Started at: Wed Nov 23 09:38:59 PST 2011
B Started at: Wed Nov 23 09:38:59 PST 2011
B Finished at: Wed Nov 23 09:39:04 PST 2011
C Finished at: Wed Nov 23 09:39:04 PST 2011
C Started at: Wed Nov 23 09:39:04 PST 2011
B Started at: Wed Nov 23 09:39:04 PST 2011

A Finished at: Wed Nov 23 09:39:09 PST 2011
B Finished at: Wed Nov 23 09:39:09 PST 2011
C Finished at: Wed Nov 23 09:39:09 PST 2011
[ 09:39 [email protected] ~/SO/bash ]$


What about forking A and B at the same time, but put A second so $! gives A's pid:

./B.sh & ./A.sh &
while ps -p $! >/dev/null; do   
./C.sh  
done 

Heres an example from my box:

[ 19:08 [email protected] ~ ]$ date
Tue Nov 22 19:08:19 PST 2011
[ 19:08 [email protected] ~ ]$ sleep 15 & sleep 20 &
[1] 1126
[2] 1127
[ 19:08 [email protected] ~ ]$ while ps -p $! > /dev/null; do sleep 1 && date; done
Tue Nov 22 19:08:26 PST 2011
Tue Nov 22 19:08:27 PST 2011
Tue Nov 22 19:08:28 PST 2011
Tue Nov 22 19:08:29 PST 2011
Tue Nov 22 19:08:31 PST 2011
Tue Nov 22 19:08:32 PST 2011
Tue Nov 22 19:08:33 PST 2011
Tue Nov 22 19:08:34 PST 2011
Tue Nov 22 19:08:35 PST 2011
Tue Nov 22 19:08:36 PST 2011
Tue Nov 22 19:08:37 PST 2011
Tue Nov 22 19:08:38 PST 2011
[1]-  Done                    sleep 15
Tue Nov 22 19:08:39 PST 2011
Tue Nov 22 19:08:40 PST 2011
Tue Nov 22 19:08:41 PST 2011
Tue Nov 22 19:08:42 PST 2011
Tue Nov 22 19:08:43 PST 2011
[2]+  Done                    sleep 20
Tue Nov 22 19:08:44 PST 2011
[ 19:08 [email protected] ~ ]$

Sign up to request clarification or add additional context in comments.

3 Comments

But this solution doesn't guarantee that B continues to repeat its execution while A executes.
@suzanne Oh, I didnt know that was also necessary. I'll think of something else.
@suzanne Check my edits at the top of the answer. I think it does what you need.
0

From your picture, it looks like you want B and C to loop while A is running, and then kill both after A completes. Here is the code for that:

# Run A in the background and get its process ID
./A.sh &
PIDA = $!

# Loop B in the background and get its process ID
while ps $PIDA >/dev/null 2>&1; do
    ./B.sh
done &
PIDB = $!

# Loop C like B, get its PID
while ps $PIDA >/dev/null 2>&1; do
    ./C.sh
done &
$PIDC = $!

# Wait until A finishes, then kill B and C
wait $PIDA
ps $PIDB >/dev/null 2>&1 && kill $PIDB
ps $PIDC >/dev/null 2>&1 && kill $PIDC

3 Comments

Does this guarantee that B repeats its execution until A finishes, if B finishes earlier than A. I don't think so. I was thinking of this solution : code ./A.sh & PIDA =$! while ps -p $PID1 >/dev/null; do ./B.sh & while ps -p $! >/dev/null; do ./C.sh done done ./B.sh done done
OK, I'm not quite clear on exactly what you want: A needs to finish. B should loop until A is finished. Do you want to kill the final execution of B or let it finish? And what about C, should it run once? Loop until A finishes like B? Should it be killed once A is done, or run to completion?
I've put image of the scenario in the above link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.