【问题标题】:Bash, confusing results for different file tests (test -f)Bash,不同文件测试的结果令人困惑(test -f)
【发布时间】:2012-08-20 00:25:04
【问题描述】:

我在 bash 中被这个表达式弄糊涂了:

$ var="" # empty var
$ test -f $var; echo $? # test if such file exists
0 # and this file exists, amazing!
$ test -f ""; echo $? # let's try doing it without var
1 # and all ok

我无法理解这种 bash 行为,也许有人可以解释一下吗?

【问题讨论】:

  • 我可以确认,在 Centos 6 下,我可以复制这个。
  • 不是 shell 或测试中的错误。只是您期望中的一个错误:-)

标签: file shell testing posix


【解决方案1】:

这是因为$var 的空扩展在test 看到它之前就被删除了。您实际上正在运行test -f,因此test 只有一个arg,即-f。根据 POSIX,像 -f 这样的单个 arg 是真的,因为它不是空的。

来自POSIX test(1) specification

1 argument:
Exit true (0) if `$1` is not null; otherwise, exit false.

永远不会对具有空文件名的文件进行测试。现在有了明确的test -f "",就有两个参数,-f 被识别为“测试是否存在路径参数”的运算符。

【讨论】:

  • 这很酷,但例如,如果我去终端(不在我的主目录中)并执行 cd "" bash 不会抱怨也不会将我重定向到我的主目录,它只是停留在我运行该命令的位置。为什么会发生这种情况?
  • @FlorinStingaciu - 因为您提供了一个空参数。将变量扩展为空与根本没有参数相同。总是引用你的扩展。
  • 对于cd,您的空参数不以/ 开头,因此它是一个相对路径。要应用相对路径,请将其连接到 pwd 并在必要时解析。 pwd + 空字符串 == pwd,因此这种行为是有道理的。
  • 您必须了解像"" 这样的显式空参数与像$var 这样的空变量扩展结果之间的区别。第一个作为 arg 传递给您运行的任何命令,第二个甚至不会成为 arg。
  • 感谢回答。我很困惑,因为方括号(等于测试)按预期工作。变量=""; [[ -f $var ]];回声$? - 返回 1。主要规则也是如此 - 始终引用您的变量 :)。
【解决方案2】:

var 为空时,$var 在是否被引用时的行为会有所不同。

test -f $var          # <=> test -f       ==>   $? is 0
test -f "$var"        # <=> test -f ""    ==>   $? is 1

所以这个例子告诉我们:我们应该引用$var

【讨论】:

    猜你喜欢
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多