1

This question already has an answer here:

In case of test -e for example:

VAR="<this is a file path: /path/to/file/or/dir"
test -e $VAR && do_something || do_anotherthing

Question: Should I use "$VAR" here?, here I don't like verbose if not necessary, because $VAR obviously in this case is a path then if it's empty string it should always fail because there's no path that is empty string, then with my logic, double quote it is not necessary.

But it case of string test, test -n for exmpale:

VAR="<this is a string"
test -n $VAR && do_something || do_anotherthing

then with my logic, $VAR should be put in double quote: "$VAR" because it can be expanded to an empty string that if not in double quote will be expanded to -n argument only and always true.

So the actual question because of that I'm in doubt of that should we only use double quotes in test command only with -n and -z against strings?

marked as duplicate by l0b0, mosvy, Kusalananda shell Jan 2 at 22:15

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • I can't parse "Should I use "$VAR" here?, here I don't like verbose if not necessary, because $VAR obviously in this case is a path then if it's empty string it should always fail because there's no path that is empty string, then with my logic, double quote it is not necessary." Can you please rephrase that, ideally with shorter sentences? – l0b0 Jan 2 at 7:07
  • @l0b0: I just don't want to use quote if not necessary. – Tuyen Pham Jan 2 at 7:55
  • 1
    I'm sorry, but that is just the wrong approach in shell scripts. – l0b0 Jan 2 at 8:31
  • @l0b0: But I see it as an abuse. – Tuyen Pham Jan 2 at 8:34
  • 1
    Filenames and paths can contain spaces. And tabs. And newlines. And wildcards. It's not safe to leave off double-quotes just because something's a path and "won't contain spaces". – Gordon Davisson Jan 2 at 9:56
4

A general rule is to double quote any variable, unless you want the shell to perform token splitting and wildcard expansion on its content.

because $VAR obviously in this case is a path then if it's empty string it should always fail [...] then with my logic, double quote it is not necessary.

On contrary. The behavior of test -e with no operands is another reason you should quote the variable in this particular case:

$ unset foo      # or foo=""
$ test -e $foo   # note this is equivalent to `test -e'
$ echo $?
0
$ test -e "$foo"
$ echo $?
1
$
  • Guess we should always double quotes variable in test command. Even though specific in my case, $VAR is forbidden from being an empty string in the first place. – Tuyen Pham Jan 2 at 7:53
  • @TuyenPham, the typical problem is filenames that contain spaces. If VAR="some file" then test -e $VAR without quotes will result in an error "binary operator expected" – glenn jackman Jan 2 at 20:55
3

See this Q&A, Greg's Wiki and the manual for explanations. tl;dr: it is not at all obvious how this works, and you should Use More Quotes™. Or to put it a different way: if your goals are correctness and maintainability, quoting properly is approximately priority 5 (after learning all the other weirdness necessary to write correct and concise shell scripts), while saving individual characters is priority 999,999+.

  • There are places it's safe to leave the double-quotes off, but figuring out where it's safe (and tracking down & fixing the bugs when you get it wrong) is more trouble than just using double-quotes consistently in the first place. – Gordon Davisson Jan 2 at 9:52
-1

This would be better, clearer:

if [[ "$VAR" ]]; then
    do_something
else
    do_anotherthing
fi

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