Bash documentation中的-a
和-e
两个选项都说:
-a file
True if file exists.
-e file
True if file exists.
试图找出差异,我运行了以下脚本:
resin_dir=/Test/Resin_wheleph/Results
if [ -e ${resin_dir} ] ; then
echo "-e ";
fi
if [ ! -e ${resin_dir} ] ; then
echo "! -e";
fi
if [ -a ${resin_dir} ] ; then
echo "-a";
fi
if [ ! -a ${resin_dir} ] ; then
echo "! -a";
fi
/Test/Resin_wheleph/Results
存在并且是一个目录。这就是我得到的:
-e
-a
! -a
这似乎有点奇怪(注意-a
和! -a
)。但是当我在类似的脚本中使用双括号(例如if [[ -e ${resin_dir} ]]
)时,它会提供合理的输出:
-e
-a
所以:
-a
和-e
选项之间有什么区别?-a
在单括号内使用会产生奇怪的结果?答案 0 :(得分:64)
我研究过,这很毛茸茸:
-a
已弃用,因此不再列在/usr/bin/test
的联机帮助页中,但仍在bash中。使用-e
。对于单个'[',bash内置行为与test
bash内置行为相同,其行为与/usr/bin/[
和/usr/bin/test
相同(一个是另一个的符号链接)。请注意-a
的效果取决于其位置:如果它位于开头,则表示file exists
。如果它位于两个表达式的中间,则表示逻辑and
。
[ ! -a /path ] && echo exists
不起作用,因为bash手册指出-a
在那里被认为是二元运算符,因此上述内容不会被解析为negate -a ..
而是作为if '!' and '/path' is true
(非空)。因此,您的脚本始终输出"-a"
(实际上测试文件),"! -a"
实际上是二进制文件and
。
对于[[
,-a
不再用作二进制and
(在那里使用&&
),因此其唯一的目的是检查那里的文件(虽然被弃用)。所以,否定实际上就是你所期望的。
答案 1 :(得分:3)
测试运算符的“-a
”选项有一个含义是一元运算符,另一个含义为二元运算符。作为二元运算符,它是'和'连词(而'-o
'是'或'连词)。作为一元运算符,它显然测试文件的存在。
autoconf
系统建议您避免使用“-a
”,因为它会导致混淆;现在我明白了为什么。实际上,在便携式shell编程中,最好将条件与“&&
”或“||
”结合起来。
我认为@litb走在正确的轨道上。当你有'! -a ${resin_dir}
'时,Bash可能会将其解释为“是字符串'!'非空,并且'$ {resin_dir}'中的字符串非空,答案是肯定的.Korn shell对此有不同的看法,而Bourne shell则是另一个视图 - 所以远离'{{ 1}}”。
在Solaris 10上:
-a
答案 2 :(得分:0)
双括号[[exp]]是一个内置的bash。在bash -a和-e中是相同的,可能是为了一些向后兼容性。
单括号[exp]是外部命令“test”的别名。在“test”中,-a是逻辑AND。虽然[没有AND $ STRING]看起来应该是假的,但测试有一些语法怪癖,这就是为什么我建议使用bash builtin [[exp]],这往往更加理智。
注意: bash确实调用/ bin / [当你使用“[”。
$ [ $UNASIGNED_VAR == "bar" ]
bash: [: ==: unary operator expected
错误显示bash调用[。 strace还显示“execve(”/ usr / bin / [“,...”