Reputation: 2836
I wonder if someone could explain why a while loop treats multipe test conditions differently to an if loop. I have 2 tests that i verified came out as True and False:
Bash$ test ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)"; echo $?
0
Bash$ test ! -e "unsentData.tmp"; echo $?
1
Bash$
When I ANDed these 2 tests into an if statement I got an aggregate of False as expected:
Bash$ if [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]; then echo "True"; else echo "False"; fi
False
Bash$
Now when I put the 2 tests into a while loop I expected a sleep until both conditions were met but instead I got immediately a true result.
Bash$ while [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]; do sleep 1; done; echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
All files Exist
unsentData.tmp
Bash$
What am I missing here? I simply want to write something that waits until the 2 conditions are met before it breaks out of the loop
A
Upvotes: 0
Views: 2168
Reputation: 125708
A while
loop executes as long as ("while") its condition is true; it sounds like you want to run the loop until its condition is true. bash has an until
loop which does exactly this:
until [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]; do
sleep 1
done
echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
Or you can just negate the condition (i.e. use "while there are files left, do..." rather than "until all files are done, do..."). In this case that just means removing the negations of the individual conditions and switching the and to an or:
while [ -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] || [ -e "unsentData.tmp" ]; do
sleep 1
done
echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
Upvotes: 1
Reputation: 25337
Your assumption is worng i think. While does execute the code between do
and done
while (as long as) the condition holds true. Your conditions combined evaluate to false, as seen in the output of your if-statement. Thus the body of the while loop never gets executed.
Try:
while ! ( [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] &&
[ ! -e "unsentData.tmp" ] )
do
sleep 1
done
echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
Upvotes: 3
Reputation: 161604
while [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]
do sleep 1
done
==>
while false
do sleep 1
done
so the do sleep 1
didn't run at all.
Upvotes: 1