1

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?

Tuyen Pham
  • 1,805
  • 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 02 '19 at 07:07
  • @l0b0: I just don't want to use quote if not necessary. – Tuyen Pham Jan 02 '19 at 07:55
  • 1
    I'm sorry, but that is just the wrong approach in shell scripts. – l0b0 Jan 02 '19 at 08:31
  • @l0b0: But I see it as an abuse. – Tuyen Pham Jan 02 '19 at 08:34
  • What do you mean? Something other than "abuse", I expect. OTOH it's extremely important to quote variables in order to process them the way you would expect >99% of the time. – l0b0 Jan 02 '19 at 08:37
  • 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 02 '19 at 09:56
  • Better to be consistent: always quote. Trying to walk along the edge of a cliff, as close as possible, because you don't like to leave no much of a gap, is more effort, and dangerous. And you have to quote it because it has a < in it. – ctrl-alt-delor Jan 02 '19 at 10:18

3 Answers3

5

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 02 '19 at 07: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 02 '19 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+.

l0b0
  • 51,350
  • 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 02 '19 at 09:52
-1

This would be better, clearer:

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