Bash if [ -d $1] returning true for empty $1

后端 未结 3 1774
时光取名叫无心
时光取名叫无心 2021-01-12 23:40

So I have the following little script and keep wondering..

#!/bin/bash

if [ -d $1 ]; then
  echo \'foo\'
else
  echo \'bar\'
fi

.. why doe

相关标签:
3条回答
  • 2021-01-13 00:00

    From: info coreutils 'test invocation' (reference found through man test):

    If EXPRESSION is omitted, test' returns false. **If EXPRESSION is a single argument,test' returns false if the argument is null and true otherwise**. The argument can be any string, including strings like -d',-1', --',--help', and --version' that most other programs would treat as options. To get help and version information, invoke the commands[ --help' and `[ --version', without the usual closing brackets.

    Highlighting properly:

    If EXPRESSION is a single argument, `test' returns false if the argument is null and true otherwise

    So whenever we do [ something ] it will return true if that something is not null:

    $ [ -d ] && echo "yes"
    yes
    $ [ -d "" ] && echo "yes"
    $ 
    $ [ -f  ] && echo "yes"
    yes
    $ [ t ] && echo "yes"
    yes
    

    Seeing the second one [ -d "" ] && echo "yes" returning false, you get the way to solve this issue: quote $1 so that -d always gets a parameter:

    if [ -d "$1" ]; then
      echo 'foo'
    else
      echo 'bar'
    fi
    
    0 讨论(0)
  • 2021-01-13 00:00

    The reason is plain and simple: The syntax does not match the case in which the -d is recognized as an operator working on a file name. It is just taken as a string, and each non-empty string is true. Only if a second parameter to -d is given, it is recognized as the operator to find out whether a given FILE is a directory.

    The same applies to all the other operators like -e, -r, etc.

    In your case, use double quotes to avoid running into that "problem":

    [ -d "$1" ]
    
    0 讨论(0)
  • 2021-01-13 00:02

    The reason that

    [ -d ] && echo y
    

    produces y is that the shell interprets it as a string in the test command and evaluates it to true. Even saying:

    [ a ] && echo y
    

    would produce y. Quoting from help test:

     string        True if string is not the null string.
    

    That is why quoting variables is recommended. Saying:

    [ -d "$1" ] && echo y
    

    should not produce y when called without arguments.

    0 讨论(0)
提交回复
热议问题