【问题标题】:Bash if [ -d $1] returning true for empty $1Bash if [ -d $1] 为空 $1 返回 true
【发布时间】:2014-02-10 13:38:40
【问题描述】:

所以我有以下小脚本并一直想知道..

#!/bin/bash

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

.. 为什么在调用 不带参数 时会打印 foo?测试 [-d ] 是如何为空字符串返回 true 的?

【问题讨论】:

  • if [ -d "$1" ]; then echo 'foo'; fi 不会在$1 为空时打印foo,但它不会回答您的问题

标签: bash if-statement


【解决方案1】:

来自:info coreutils 'test invocation'(参考通过man test找到):

如果省略 EXPRESSION,test' returns false. **If EXPRESSION is a single argument,test' 如果参数为 null 且为 true,则返回 false 除此以外**。参数可以是任何字符串,包括字符串 -d',-1'、--',--help' 和 --version' that most other programs would treat as options. To get help and version information, invoke the commands[ --help' 和 `[ --version',没有通常的关闭 括号。

正确突出显示:

如果 EXPRESSION 是单个参数,如果 参数为空,否则为真

所以每当我们执行[ something ] 时,如果something 不为空,它将返回true

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

看到第二个[ -d "" ] && echo "yes"返回false,你就有了解决这个问题的方法:引用$1这样-d总是得到一个参数:

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

【讨论】:

    【解决方案2】:

    原因很简单:语法与-d 被识别为处理文件名的运算符的情况不匹配。它只是被当作一个字符串,并且每个非空字符串都是真的。只有给-d的第二个参数,才被识别为判断给定FILE是否为目录的操作符。

    这同样适用于所有其他运算符,如-e-r 等。

    在您的情况下,请使用双引号以避免遇到该“问题”:

    [ -d "$1" ]
    

    【讨论】:

      【解决方案3】:

      原因

      [ -d ] && echo y
      

      产生y 是shell 在test 命令中将其解释为字符串 并将其评估为真。甚至说:

      [ a ] && echo y
      

      会产生y。引用help test:

       string        True if string is not the null string.
      

      这就是建议引用变量的原因。说:

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

      不带参数调用时不应产生y

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-10
        • 1970-01-01
        • 2015-01-16
        • 1970-01-01
        • 2019-01-09
        相关资源
        最近更新 更多