5

I want to decide whether to always omit quotes for variables appearing withing a Bash [[ test. I interpret the man page to say that it is permissible to do so without any loss of correctness.


I devised this simplistic "test" to verify my thinking and the "expected behaviour" but it may prove absolutely nothing, take a look at it:

x='1 == 2 &&'
if [[ $x == '1 == 2 &&' ]]; then
    echo yes
else
    echo no
fi

Note I am not writing this as such:

x='1 == 2 &&'
if [[ "$x" == '1 == 2 &&' ]]; then
    echo yes
else
    echo no
fi

which so far has always been my style, for consistency if nothing else.


Is is safe to switch my coding convention to always omit quotes for variables appearing within [[ tests?

I am trying to learn Bash and I am trying to do so picking up good habits, good style and correctness..

2
  • 8
    One caveat: On the right side of == and != if it isn't quoted it is treated as a pattern rather than a string. So if x="Now is" and y="[nN]ow*" then [[ $x == "$y" ]] is false while [[ $x == $y ]] is true. That could bite you at some point. Commented Mar 22, 2013 at 22:15
  • Excellent point! Thanks!! I did mean just the left side though.. (I should have specified that). Was glad to learn your insight though.. Commented Mar 22, 2013 at 22:33

2 Answers 2

9

The key thing to remember is that quotes and escaping within pattern matching contexts always cause their contents to become literal. Quoting on the left hand side of an == within [[ is never necessary, only the right side is interpreted as a pattern. Quoting on the right hand side is necessary if you want a literal match and to avoid interpretation of pattern metacharacters within the variable.

In other words, [ "$x" = "$x" ] and [[ $x == "$x" ]] are mostly equivalent, and of course in Bash the latter should be preferred.

One quick tip: think of the operators of the [[ ]] compound comand as being the same grammar-wise as other control operators such as elif, do, ;;, and ;;& (though technically in the manual they're in their own category). They're really delimiters of sections of a compound command, which is how they achieve seemingly magical properties like the ability to short-circuit expansions. This should help to clarify a lot of the behavior of [[, and why it's distinct from e.g. the arithmetic operators, which are not like that.

More examples: http://mywiki.wooledge.org/BashFAQ/031#Theory

Sign up to request clarification or add additional context in comments.

6 Comments

Your input is always so much appreciated! Why would "the latter" be preferable? To use a feature that it's there? I don't see how quoting the left side "needlessly" would harm in any way.. is there a scenario in which it would?
@Robottinosino Not that I'm aware of. Since quotes are never required in that context, not including them makes this fact apparent. If you use them randomly or even redundantly all the time, it's much easier to become confused because people will see examples that are quoted in some places and not in others. There are some places where you really don't want to quote for various reasons. If it's random quoting where optional, it isn't clear in which cases it's optional and in which they are omitted for a real effect. Sometimes being explicit means allowing implicit things to happen consistently
I am not convinced by this: "Sometimes being explicit means allowing implicit things to happen consistently" but I am going to accept your answer more based on the respect I have for your experience and your general helpfulness, which is really motivating..
This isn't a normal sane language. In ordinary argument contexts, most of the time they are there to essentially disable a misfeature that comes from Bourne baggage, and you're explicitly causing that effect. In an exceptional case like this (or another example is case ... in), you aren't really being explicit about anything. You're just adding more quotes where they don't do anything. You really want to know where the quotes have effect and make that part as obvious as possible. This isn't too important. Moderately experienced scriptwriters can deal with it either way.
Thanks! Your bar of "moderately experienced" may be a bit high for me.. ;)
|
6

No. You should not get in the habit of always omitting quotes, even if they appear within [[ tests. Bash is famous for burning people for leaving off quotes :-)

In bash the [[ ]] should always evaluate as an expression, so the script will continue to function. The risk is that a logic error may pop up unnoticed. In all cases that I can think of off the top of my head it would be fine. However, quotes allow you to be specific about what you want, and are also self-documenting in addition to being safer.

Consider this expression:

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then

It would still work without the quotes because it is in between [[ ]], but the quotes are clarifying and do not cause any issues.

At any rate, this is my opinion as a guy who has received a royal hosing at the hand of Bash because I failed to put " " around something that needed them :'(

My bash hacking friend once said, "use quotes liberally in Bash." That advice has served me well.

3 Comments

Explicit is better than implicit, as the old Python-inspired adagio goes. That's the way I have always coded, as per my original post. So I agree with you. You know, sometimes people get upset even due to the UUOC so.. you can't please everybody..
Implicit is better than explicit for me. Bash has a lot of context-sensitive detail going on. It is very much required to know the exact rules. If I see some potentially redundant piece of syntax, it's unfortunate that I have to ask myself whether the coder knew what they were doing when they put it there. Because a complex script can come to depend upon small details, at least when I write things, it helps to know I put some syntax there for a reason. The best style likely depends upon your experience level.
@ormaaj: I mostly agree, but in bash context I tend to think of putting things in double-quotes as the default, and anything that isn't double-quoted will make me stop and think about whether there's a reason, and whether the coder knew what they were doing... So essentially the same reasoning leads me to the opposite conclusion in this case.

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.