0

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

3 Answers 3

3

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/)"
Sign up to request clarification or add additional context in comments.

2 Comments

That syntax does not seem to be correct. I got the error: -bash: syntax error near unexpected token `('. But I see your point
It still did not work. All the negations make it very confusing. Gordons suggestion of using an until loop set me in the correct track. Thanks
1

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/)"

1 Comment

The until loop worked when I removed the negation. It was the direction I was looking for but overlooked. Thanks. I wanted to wait until both xml files and unsentData.tmp were present so no negation in either of the ANDed test conditions worked
1
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.