Skip to content

Comment on Writing Robust Bash Shell Scripts

Comments

He suggests using

    if [ "$filename" = "foo" ]; 
Why not
    if [[ $filename == "foo" ]];
?

EDIT: aware of the fact that [[ ]] is a bash extension, but the actual title of the post is "Writing Robust Bash Shell Scripts", implying that it should be using the best stuff for BASH.

    $ cat foo.sh
    #!/bin/bash
    echo $BASH_VERSION
    unset filename
    if [[ $filename == "foo" ]];
    $ ./foo.sh
    4.1.2(1)-release
    ./foo.sh: line 5: syntax error: unexpected end of file
If $filename evaluates to an empty string, then the last line of code becomes
    if [[ == "foo" ]];
Similarly, if $filename evaluates to a b c, then the last line of code becomes
    if [[ a b c == "foo" ]];
The bash interpreter has problems with both of these.

No, that is just wrong. In double-brackets, bash will handle expansion and testing of unset variables and variables with spaces just fine, because word splitting and pathname expansion are not performed in double braces -- they are shell syntax, as opposed to single brackets, which are commands. Your syntax error happened because you don't have a fi matching that if.

As a counterexample:

  (echo $BASH_VERSION; 
  foo=foo; [[ $foo = foo ]] && echo $foo; 
  foo="1 2 3"; [[ $foo = "1 2 3" ]] && echo $foo; 
  foo=''; echo ${foo?"No foo for you"}; 
  unset foo; echo ${foo?"No foo for you"})
  4.2.10(1)-release
  foo
  1 2 3
  
  bash: foo: No foo for you
That last one is one of the few ways you can tell whether a variable is unset or merely set to an empty string.

lrn2bash.

First is Posix, the second is bash. The first is more portable.

The title of the article is "Writing Robust Bash Shell Scripts", which differs from the title of the HN post.

Or

    if [[ $filename == foo ]];

Which is the correct idiomatic way. The article's author is wrong in enclosing foo in quotes.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.