在 bash 会话中,我可以成功执行以下命令:
[ -e /tmp -o -f /tmp ]
但是,以下命令失败并显示错误消息[: 争论太多:
[ -t /tmp -o -f /tmp ]
我无法解释为什么第二个命令失败,因为两个命令-e
和替换-t
都是一元运算符,并且我没有更改整个表达式的语法。
答案1
虽然该-t
运算符是一元运算符,需要 bash 中的数字(而不是 ksh 或 zsh 中的算术表达式),但这并不能解释您收到的错误。
它既没有解释原因[ -t /tmp ]
,也[ X -a -t -a Y ]
没有错误地返回 false。
test
如果你查看/ builtin的代码[
,你会发现有那里的残余物从那时起[ -t ]
,[ -t 1 ]
它就不再被删除了,并且代码已更新为遵循 POSIX 算法。
看这个错误报告了解详情。
另请注意,二元-a
/-o
运算符应该不是使用。它们已被 POSIX 弃用数十年,并且导致测试表达式不可靠。
使用:
[ -d /tmp ] || [ -f /tmp ]
反而。
请注意,-f
暗示-e
、 so[ -e /tmp -o -f /tmp ]
或[ -e /tmp ] || [ -f /tmp ]
没有多大意义,可以编写[ -e /tmp ]
为测试是否/tmp
存在(在符号链接解析之后)是否是一个常规的文件 ( -f
) 或不文件。
在zsh
:
$ zsh -c '[ -t /tmp ]'
zsh:1: bad math expression: operand expected at `/tmp'
/tmp
确实是一个糟糕的数学表达, 这预期操作数指的是/
除法数学运算符,而不是-t
[
运算符。
$ zsh -c '[ -t foo/tmp ]'
zsh:1: division by zero
这次是一个有效的数学表达式(foo
变量除以tmp
变量),但由于未设置而导致除以 0 $tmp
,因此被视为 0。
$ zsh -o nounset -c '[ -t foo/tmp ]'
zsh:1: tmp: parameter not set
该nounset
选项对于检测未初始化的变量很有用。
$ foo=4 tmp=2 zsh -o nounset -c '[ -t foo/tmp ] &&
printf "fd %d is open on a tty device\n" foo/tmp'
fd 2 is open on a tty device