Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you aren't quoting the left hand side, you still need it if the left side is an empty string:

  $ foo=""
  $ [ $foo = "" ]
  -sh: [: =: unary operator expected
  $ [ x$foo = "x" ]
  $ echo $?
  0
I'm not arguing that this is a good idea, merely observing that this case remains.

Empty strings had always been the case that I'd been taught required the x-hack.



You don't need the x-hack for strings. In shell, a widely-recommended form for ANY expansion of a variable uses quoting unless you have special requirements. E.g., normally don't use $foo, use "$foo". Tools like shellcheck enforce this. Not ideal, but not a big deal either.


> in shell

This advice is highly dependent on specific choice of shell. This kind of quoting is unnecessary and discouraged in zsh, for example.


I mean for using POSIX standard (Bourne) shell mechanisms.

If you use nonstandard mechanisms, then whatever.


Isn't this one of the things that bash [[ ]] explicitly fixes?


Well, on the left side. On the right side, [[ still requires you to quote, otherwise:

    % bash -c 'a=xy; b="x*"; [[ $a == $b ]] && echo "$a == $b"'
    xy == x*
My hot take is that you should avoid using [[, preferring to use [, which at least pretends to work like a normal program that can be invoked using normal quoting rules—it just interprets a funky mini-language on its command-line arguments. [[ is some exotic thing that seems reasonable at first glance but follows no rules but its own and varies its behavior depending on syntactic nits that literally cannot possibly matter and aren't even distinguishable for normal programs.

And then just quote consistently, which is something you need know how to do with almost every other line of a shell script anyway!


> you should avoid using [[, preferring to use [

I tend to agree, and have taken this one step further, preferring the "test" command:

  if test "$a" = "foo" ; then
I do this for a few reasons:

- "Subsetting" your language can be beneficial: https://wiki.c2.com/?LanguageSubset

- "test" reinforces the notion that this is just the name of a program, not a syntax construct, which encourages using other programs as predicates, e.g. 'if which -s foo'.

- "man test" doesn't force you to wade through a 5,000 line man page.

Recent example: https://leopard.sh/leopard.sh


Wow haven’t seen a c2 link not from me in so long. So much good and interesting thought there.


Well techincally... the == and != operator matches the LHS against the pattern on the RHS.

So [[ $a == "$b" ]] works.

    $ shellcheck oops.sh
    
    In oops.sh line 4:
    [[ $a == $b ]]
             ^-- SC2053 (warning): Quote the right-hand side of == in [[ ]] to prevent glob matching.
    
    For more information:
      https://www.shellcheck.net/wiki/SC2053 -- Quote the right-hand side of == i...
Unlike the bugs that the x$var works around this is all in the manual!

https://www.gnu.org/software/bash/manual/bash.html#index-_00...


I hope not, because $empty is necessary when you actually want to elide a missing value, like Python's `filter`


What a horrible language:x


It's horrible but it's home for a lot of us.


more like holm for you.


The parent I think is getting two things mixed up.

    [[ $var == "" ]]
works as you describe and as expected. What the parent is talking about is when you have an invocation like

    my_program $opt
    my_program "$opt"
Which when empty will evaluate to

    my_program
    my_program ""
respectively.


Why would someone want to intentionally write broken code and then hack around it, instead of the obvious correct thing?

There are lots of ways to hack around lots of ways to break code.


Because when we try something that works, we have a bias that it must be the right way to do it.

It's probably the biggest drawback to self-learning.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: