Bash 文件存在测试始终为真

tri*_*lef 5 shell bash shell-script quoting test

我有以下 bash 脚本行来测试文件是否存在:

MYAPPPATH=$(find $APPDIR -iname myapp* -print)
if [ -e $MYAPPPATH ]
then
    echo "File exists" 
fi
Run Code Online (Sandbox Code Playgroud)

但是,当以“myapp”开头的文件不存在时,因此 MYAPPPATH='',上述检查再次成功。看看使用时会发生什么set -x,但文件不存在:

++ find /path/to/app -iname 'myapp*' -print
+ MYAPPPATH=
+ '[' -e ']'
+ echo 'File exists'
Run Code Online (Sandbox Code Playgroud)

这是什么原因?

我需要做什么才能使这项工作按预期进行?

cuo*_*glm 13

当您的变量为空时,您的命令变为:

[ -e ]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您[..]使用一个参数调用-e。字符串"-e"不为空,所以test返回真。

此行为由POSIX 测试定义:

在下面的列表中,$1、$2、$3 和 $4 代表提交给测试的参数:

0 个参数:

退出假 (1)。

1 论点:

如果 $1 不为空,则退出真 (0);否则,退出假。

....

为了使它工作,你必须双引号你的变量

[ -e "$MYAPPPATH" ]
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为-e参数是空字符串是假的。


Hau*_*ing 5

习惯引用变量。总是引用它们;在必要时防止误判:

if [ -e "$MYAPPPATH" ]
Run Code Online (Sandbox Code Playgroud)

使用 bash 特定的复合命令不会发生这种情况:

if [[ -e $MYAPPPATH ]]
Run Code Online (Sandbox Code Playgroud)

  • 严格来说,`[[...]]` 是由 `bash` 从 `ksh` 复制而来的。`zsh` 也支持它。所以它不是特定于 bash 的(尽管它不是标准/POSIX sh 语法,因此不应在 `sh` 脚本中使用)。 (4认同)