Reputation: 395
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
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
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