LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 02-21-2012, 02:08 PM   #1
Ronayn
Member
 
Registered: Jan 2006
Posts: 55

Rep: Reputation: 0
bash scripting


Hello,

I am working on a bash script that does some initial setup for, then launches several applications (in the background). These applications (4 in total) execute simultaneously and coordinate with each other. The all continue to execute until closed by the user.

What I'd like to know is if it is possible to program the bash script that launches these apps to "lie and wait" for all of them to exit? (So that some cleanup can be done.)

Here's what my script looks like...

Code:
#!/bin/bash

< Setup code is here>


gnome-terminal -t "$BUILD_NAME: App #1" -e "$APP1 $BUILD_NAME $HOST_NAME $RUN_DIR" &
sleep 1

COMMAND="mpiexec -machinefile ../cfg/machine-file.txt -n 4 $APP2"
gnome-terminal -t "$BUILD_NAME: App #2"  -e "$COMMAND" &
sleep 1

COMMAND="$APP3 -display $(hostname):0"
gnome-terminal -t "$BUILD_NAME: App #3"  -e "$COMMAND" &
sleep 1

COMMAND="$APP4 -display $(hostname):0"
gnome-terminal -t "$BUILD_NAME: App #4"  -e "$COMMAND" &
sleep 1
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 02-21-2012, 02:14 PM   #2
jhwilliams
Senior Member
 
Registered: Apr 2007
Location: Portland, OR
Distribution: Debian, Android, LFS
Posts: 1,168

Rep: Reputation: 207Reputation: 207Reputation: 207
Absolutely.

Something like this would work:
Code:
pid_list=''

command_foo &
pid_list="$pid_list $!"

comand_bar &
pid_list="$pid_list $!"

# Process Barrier
while [ -n "$pid_list" ]; do
    echo "Waiting for processes to terminate: $pid_list"
    sleep 5
done

# Everything's done now.

Last edited by jhwilliams; 02-21-2012 at 02:18 PM.
 
1 members found this post helpful.
Old 02-21-2012, 02:52 PM   #3
GamezR2EZ
Member
 
Registered: Jan 2009
Posts: 31

Rep: Reputation: 4
jhwilliams has a great solution. Another is making use of the wait command.

Code:
command_foo &
fooprocess=$!

wait $fooprocess
EDIT: corrected code

Last edited by GamezR2EZ; 02-21-2012 at 05:27 PM.
 
2 members found this post helpful.
Old 02-21-2012, 03:01 PM   #4
jhwilliams
Senior Member
 
Registered: Apr 2007
Location: Portland, OR
Distribution: Debian, Android, LFS
Posts: 1,168

Rep: Reputation: 207Reputation: 207Reputation: 207
Quote:
Originally Posted by GamezR2EZ View Post
jhwilliams has a great solution. Another is making use of the wait command.

Code:
command_foo &
fooprocess="$pid_list $!"

wait $fooprocess
I like this better.
 
1 members found this post helpful.
Old 02-21-2012, 03:55 PM   #5
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
I know jhwilliams said "something like this" but I just wanted to point out that his example, as written, would be an infinite loop. Specifically:
Code:
[ -n "$pid_list" ]
would never evaluate to false once the loop is entered. In other words, there is nothing inside the loop to change the value of the pid_list variable.

I would also vote for wait. Though, perhaps a merger of the efforts of jhwilliams and GamezR2EZ:
Code:
#!/bin/bash

# < Setup code is here>

# A variable containing a space-separated list of all process IDs spawned
pid_list=''

# Process #1
gnome-terminal -t "$BUILD_NAME: App #1" -e "$APP1 $BUILD_NAME $HOST_NAME $RUN_DIR" &
pid_list="$pid_list $!"
sleep 1

# Process #2
COMMAND="mpiexec -machinefile ../cfg/machine-file.txt -n 4 $APP2"
gnome-terminal -t "$BUILD_NAME: App #2"  -e "$COMMAND" &
pid_list="$pid_list $!"
sleep 1

# Process #3
COMMAND="$APP3 -display $(hostname):0"
gnome-terminal -t "$BUILD_NAME: App #3"  -e "$COMMAND" &
pid_list="$pid_list $!"
sleep 1

# Process #4
COMMAND="$APP4 -display $(hostname):0"
gnome-terminal -t "$BUILD_NAME: App #4"  -e "$COMMAND" &
pid_list="$pid_list $!"
sleep 1

for processID in ${pid_list} ; do
  wait ${processID}
done

# < Cleanup code is here>
NOTE: The pid_list assignment statements must come before the sleep command. Otherwise, you'll get the process ID of the sleep command and not the gnome-terminal.

It waits for each process ID in sequence. There is a danger in this approach. Say process #1 runs for days, but process 4 runs for a few seconds. There is a chance that process 4's process ID will be re-used by the system. So, it's possible that the script would end up waiting on a process it did not spawn itself.

To avoid that, you probably need to use a polling loop (like in jhwilliams original post) that checks each process ID in the list once every X seconds/minutes/hours. Then, if the process is gone, remove that ID from your checklist.

EDIT:
Corrected a few things... I referenced "waitpid" instead of "wait" which is incorrect. "waitpid" is a function in C... not a shell command.

Last edited by Dark_Helmet; 02-21-2012 at 03:59 PM.
 
2 members found this post helpful.
Old 02-22-2012, 05:02 AM   #6
Ronayn
Member
 
Registered: Jan 2006
Posts: 55

Original Poster
Rep: Reputation: 0
Wow! Thanks to all for the replies!
 
Old 02-23-2012, 09:17 AM   #7
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 13.1
Posts: 1,320

Rep: Reputation: 252Reputation: 252Reputation: 252
Is there any reason not to use wait without any process ID? It will wait for all spawned processes if none is given.

NB: There is the command jobs to list all spawned background processes and jobs -p to list all process IDs at once.
 
Old 03-16-2012, 05:13 AM   #8
s4sandeep
LQ Newbie
 
Registered: Mar 2012
Posts: 5

Rep: Reputation: Disabled
word count program help

Hi,

I have recently started working in bash script and currently creating short programs and I could not find the path to create a new thread, I just tried to create the program for counting the words in a file but its not running successfully.

program:

#!/bin/bash
num=`wc -l test1.sh`
echo $num
if
[ "$num" -gt "1" ]
then
echo "this is gt 1"
fi

other information:
the number of lines in test1.sh file is 3.

error:
verma@verma-Lenovo-G560:~/shell-scripts$ sh test.sh
3 test1.sh
[: 8: Illegal number: 3 test1.sh


Could someone please help on same,thanks in advance.

Regards
Sandeep Verma
 
Old 03-16-2012, 05:46 AM   #9
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 13.1
Posts: 1,320

Rep: Reputation: 252Reputation: 252Reputation: 252
Please check the output of the wc command, this needs to be trimmed.

NB: In the forum overview “Forum Tools” (near the right side) => “Post New Thread”
 
Old 03-20-2012, 03:33 AM   #10
s4sandeep
LQ Newbie
 
Registered: Mar 2012
Posts: 5

Rep: Reputation: Disabled
Quote:
Originally Posted by Reuti View Post
Please check the output of the wc command, this needs to be trimmed.

NB: In the forum overview “Forum Tools” (near the right side) => “Post New Thread”
The issue is still pending, can you tell me how can I trim this?
 
Old 03-20-2012, 03:59 AM   #11
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 13.1
Posts: 1,320

Rep: Reputation: 252Reputation: 252Reputation: 252
The output of wc includes the filename, and there is no option to leave it out, hence a reference to the plain line count could be:
Code:
${num%% *}
This will remove the blank and anything behind.

Instead of wc you could also use awk to get the number of line directly without a filename:
Code:
awk 'END {print NR}' test1.sh
 
Old 03-20-2012, 04:46 AM   #12
s4sandeep
LQ Newbie
 
Registered: Mar 2012
Posts: 5

Rep: Reputation: Disabled
Quote:
Originally Posted by Reuti View Post
The output of wc includes the filename, and there is no option to leave it out, hence a reference to the plain line count could be:
Code:
${num%% *}
This will remove the blank and anything behind.

Instead of wc you could also use awk to get the number of line directly without a filename:
Code:
awk 'END {print NR}' test1.sh

Many thanks reuti! This resolved the problem!!
 
  


Reply

Tags
bash scripting


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
bash scripting ninjafairy Programming 11 05-18-2011 10:00 AM
Reading a bash variable in bash scripting problem freeindy Programming 3 11-27-2008 02:29 AM
Need help with bash scripting whited Programming 6 10-15-2007 08:54 PM
Bash scripting disruptive Programming 5 06-29-2006 03:49 PM
HELP with BASH scripting atwah Linux - Newbie 6 09-09-2003 01:10 AM


All times are GMT -5. The time now is 05:00 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration