Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have the following bash script:

while [ $loop == "true" ]
   do
     //do stuff
   done

but it says error at [.

Also this runs as a daemon, when the stop argument is passed to the script...the loop should. I'm guessing setting $loop to false will automatically end the loop.

share|improve this question
    
"... it says error at [." Really? –  Ignacio Vazquez-Abrams Jan 9 '12 at 1:11
    
Have a -1 for not giving nor properly describing the error message. –  JdeBP Jan 9 '12 at 11:28
add comment

2 Answers

up vote 1 down vote accepted

The best way to type this would be:

while [ "$loop" = "true" ]

Read the section "Working out the test-command" at the following URL:
http://wiki.bash-hackers.org/syntax/quoting

share|improve this answer
2  
All values in bash are strings. The quotes have nothing to do with that. –  Ignacio Vazquez-Abrams Jan 9 '12 at 1:17
2  
The quotes makes it work. And = compares strings, compared to (for example) -eq that compares integers. Check Advanced Bash Scripting Guide for more information "Note that integer and string comparison use a different set of operators.": tldp.org/LDP/abs/html/comparison-ops.html –  Mattias Ahnberg Jan 9 '12 at 1:21
    
Or well, you are right, the "" in itself doesn't make it a string, you might aswell use: $loop = true but bash still makes difference between strings and integers. Updated the answer slightly. –  Mattias Ahnberg Jan 9 '12 at 1:23
    
The reasoning is still incorrect. $ [ true = "true" ] ; echo $? 0 –  Ignacio Vazquez-Abrams Jan 9 '12 at 1:25
6  
You know, telling someone they are wrong without explaining and properly correcting is kindof pointless and dumb? –  Mattias Ahnberg Jan 9 '12 at 1:27
show 2 more comments

M. Vazquez-Abrams is quite right. This is nothing to do with quotation marks making things that are already strings into strings, or some wrongheaded idea that = in bash's built-in [ command is anything other than a string comparison. (Read § 6.4 of the Bash User Manual, people!) It's everything to do with what happens to empty fields after field-splitting turns words into fields.

If the shell variable loop is empty or null, then $loop expands to an empty field. After field splitting, empty fields are discarded. Note that field splitting and the check for empty fields precedes quote removal. So "$loop" expands to the field "", which is not empty and is thus not removed. After quote removal it is then an empty field, that becomes an empty argument to the command.

The [ command requires its = operator to have two operands, fore and aft. Anything else is a syntax error. Since an empty field is removed, the sequence of words

[ $loop = true ]
expands to four fields

  1. [
  2. =
  3. true
  4. ]

when the [ command needs five to be syntactically correct:

  1. [
  2.  
  3. =
  4. true
  5. ]

Of course, the empty string is not equal to the four-character string true, and the command's exit status is non-zero.

Again, all of this is in the Bash User Manual, in §3.5 and §3.5.7. The manual is your friend.

share|improve this answer
    
Oh yes, you are ofcourse right. Well put! I much more appreciate these types of corrections and explanations though than Mr Vazquez-Abrams arrogant comments just pointing out that someone is wrong without bothering to explain or clarify. Hardly helpful. I phrased myself badly with converting to string, but I meant there is a difference between strings and integers in how you're supposed to loop them. And I always have a habit of putting my tests/strings within "" to handle spaces properly. :) I also wrongly assumed that $loop was set to "true", while it might not have been. –  Mattias Ahnberg Jan 9 '12 at 12:59
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.