LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-01-2008, 12:22 AM   #1
nonoitall
Member
 
Registered: Feb 2005
Posts: 75

Rep: Reputation: 16
Wait for one of two processes to complete in a shell script


Title says it all pretty much. Let's say I start process A, then start process B. How can I wait until either A or B completes (without waiting for both to complete), and then continue execution of my script?
 
Old 06-01-2008, 12:57 AM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,572

Rep: Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885Reputation: 1885
Code:
processA &
pidA=$!

processB &
pidB=$!

if <condition here> ; then
  wait $pidA
else
  wait $pidB
fi
EDIT: looking at it now, I have no I have no idea how I interpreted your question this way...

Last edited by ntubski; 06-02-2008 at 01:18 PM.
 
Old 06-01-2008, 01:50 AM   #3
nonoitall
Member
 
Registered: Feb 2005
Posts: 75

Original Poster
Rep: Reputation: 16
Maybe I didn't explain my problem clearly in my first post. I launch two processes, A and B. If A finishes before B, I want my script to resume as soon as A finishes. If B finishes before A, I want my script to resume as soon as B finishes.
 
Old 06-01-2008, 05:29 AM   #4
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Code:
#!/bin/bash

t1=$(($RANDOM % 10))
t2=$(($RANDOM % 10))
echo "$(date +%T)|times are: $t1 and $t2"
sleep $t1 &
sleep $t2 &

keep_waiting=1
while true; do
        running=$(jobs |wc -l)
        if [ $running -gt 1 ]; then
                echo "$(date +%T)|still $running running... sleeping"
                sleep 1
        else
                echo "$(date +%T)|only $running running now... ending loop"
                break
        fi
done

echo "$(date +%T)|at least on of them finished..."
wait
echo "$(date +%T)|now both ar done"
 
Old 06-01-2008, 02:49 PM   #5
nonoitall
Member
 
Registered: Feb 2005
Posts: 75

Original Poster
Rep: Reputation: 16
Cool, polling never even occurred to me. I'll give that a shot - thanks!
 
Old 06-01-2008, 04:08 PM   #6
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 77
You could always exploit SIGCHLD. Here is one way to do so (there are many others in a similar fashion).
Code:
#!/bin/sh

echo "Starting both processes…"

sh -c 'trap "exit" CHLD
       process1 & process2 & wait'

echo "One process has exited."
Edit:
It seems that the above will not work if sh is symlinked to bash. It will work on ksh, zsh, dash, etc., but for some reason, trapping SIGCHLD doesn’t work in bash in a script.

As a workaround (if sh is a symlink to bash on your system), try this:
Code:
#!/bin/sh

echo "Starting both processes…"

sh -c 'set -m
       trap "exit" CHLD
       process1 & process2 & wait'

echo "One process has exited."

Last edited by osor; 06-01-2008 at 06:08 PM.
 
Old 06-02-2008, 03:00 AM   #7
nonoitall
Member
 
Registered: Feb 2005
Posts: 75

Original Poster
Rep: Reputation: 16
Thanks!
 
Old 06-05-2008, 08:02 PM   #8
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
Is this an OR situation or an AND? -- you do want to resume when EITHER completes, not when BOTH are done, don't you?

I ask because I assume that "either ... or ..." in your OP means what it says, whereas to me the logic in both post #4 & #6 seems to be AND logic.
 
Old 06-05-2008, 09:34 PM   #9
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 77
Quote:
Originally Posted by archtoad6 View Post
I ask because I assume that "either ... or ..." in your OP means what it says, whereas to me the logic in both post #4 & #6 seems to be AND logic.
I interpreted the question as “either … or …” and my post logic reflects this. I am not sure how you read otherwise. The line “One process has exited.” will be printed when either process exits.

Btw, AND logic is much easier to do (at least in shell), since the wait builtin may take multiple pid or job-id arguments, and will wait for all of them.
 
Old 06-05-2008, 10:24 PM   #10
nonoitall
Member
 
Registered: Feb 2005
Posts: 75

Original Poster
Rep: Reputation: 16
It was either or. I'm automating a series of tasks, keeping two running at a time (to make better use of a dual-core processor). So, as soon as one task finishes, another should start. Since the tasks vary in length, I'm arranging it like a queue where each 'slot' takes a new task of a list when its current process has finished.
 
Old 06-06-2008, 03:10 PM   #11
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 77
Quote:
Originally Posted by nonoitall View Post
I'm automating a series of tasks, keeping two running at a time (to make better use of a dual-core processor). So, as soon as one task finishes, another should start. Since the tasks vary in length, I'm arranging it like a queue where each 'slot' takes a new task of a list when its current process has finished.
You can do this using SIGCHLD as well (although it would be much easier in C).

Try out the following (it should do what you want, barring race conditions):
Code:
#!/bin/bash

SLOTS=2

(	set -m

	trap 	"if read next ; then
			eval \$next &
		fi" CHLD

	for ((i = 0; i < $SLOTS; i++)); do
		read proc
		eval "$proc" &
	done

	wait
) << __EOF__
zenity --info --text=1st
zenity --info --text=2nd
zenity --info --text=3rd
zenity --info --text=4th
zenity --info --text=5th
zenity --info --text=6th
__EOF__

echo "Rest of script goes here"
I am not sure, however, of the portability to other shells.

When you say queue, generally you mean a First-In, First-Out (FIFO), so you could very well use pipes (named or anonymous) instead of hardcoding as the method of sending commands.

Last edited by osor; 06-10-2008 at 04:10 PM. Reason: remove race condition
 
Old 06-10-2008, 04:10 PM   #12
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 77
I haven’t been here for awhile, but if anyone is still interested, I fixed the race condition in the above script. Basically, it involves setting up the SIGCHLD handler first, and then ensuring there are no calls to external programs (except those you have on queue). So that means instead of using seq(…), you have to use a counter.

I have edited the above accordingly, and it works (for me) on bash and zsh.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
my shell script dont work complete mehxh1979 Linux - Software 5 09-27-2007 11:09 AM
Hi, I am a complete n00b in need of help executing her bash shell script. savoirefaire Linux - Newbie 4 03-12-2007 06:14 AM
can you do threading or multiple processes in a shell script? BrianK Programming 8 08-07-2006 04:40 PM
Shell-Script for killing processes oulevon Programming 4 02-14-2006 10:49 AM
shell script to kill all processes on specified port varunbihani Linux - General 1 04-19-2005 05:39 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration