fabioln79
fabioln79

Reputation: 395

bash different loops in background using & and wait

I've taken a look to the related topics but I did not found an answer.

Here's my problem:

I'm trying to put these commands that I usually run NOT in a for loop into two separate for loops

original commands:

command1 &
command2 &

wait

command 3

This obviously starts two commands in background and, after BOTH are finished, it starts the command 3

Now here there's my for loop script:

file1=directory1/*.txt

for i in $file1;

do

command1 ${i} > ${i}.test & # I know, it will generate files like ".txt.test". It's ok.

done &


file2=directory2/*.txt

for i2 in $file2;

do

command1 ${i2} > ${i2}.test & 

done &

wait

command3

Now there is somethig wrong in my script because sometimes when is performing the command 3 I can find some jobs from command1 or command2 EVEN if I put the "wait".

I've tried different option like the second "done" without &. I've tried also two wait..but everything I do...I mess up all the jobs :(

Where is my mistake (please...be polite :P)?

Thank you

Fabio

Upvotes: 4

Views: 9603

Answers (2)

curious_prism
curious_prism

Reputation: 349

There is no need for you to put the ampersand (&) after each done, you can simply put it after each command and all jobs from both loops will be put into the background and a single wait will do the trick.

for i in $( seq 1 3 ); do
    command1 "$i" > "$i.test" &
done

for i in $( seq 4 6 ); do
    command2 "$i" > "$i.test" &
done

wait

command3

An alternative approach is to store the pid of each background process by making use of $!, like so

pid=""
command & pid="$pid $!"
wait $pid

Upvotes: 0

Radi R
Radi R

Reputation: 13

Save both "for" loops, but remove all "&" from them, as separate files:loop1,loop2. chmod a+rx loop1 loop2; and execute:

loop1 &
loop2 &
wait
command3

I don't know the behaviour of "done &", better don't use it.
Your code is executing everything at the same time. I am assumming that you want 2 threads.

Edit: Single script solution:

script1=`mktemp /tmp/.script.XXXXXX`;
cat >$script1 <<END
for i in directory1/*.txt; do
  command1 ${i} > ${i}.test;
done 
END

script2=`mktemp /tmp/.script.XXXXXX`;
cat >$script2 <<END
for i in directory2/*.txt; do
  command1 ${i} > ${i}.test;
done 
END

chmod u+rx $script1 $script2
$script1 &
$script2 &
wait;
command3

/bin/rm $script1 $script2

Upvotes: 1

Related Questions