这不是一个真正的问题(虽然我最后有一个),而是我想分享的问题的解决方案,以防它帮助其他人。
我打开新终端时获得bash: [: too many arguments
的时间最长(特别是安装了bash-completion macport的OS X上的iTerm2)。此错误源自文件if [ -n "$BASH_VERSION" -a -n "$PS1" -a -z "$BASH_COMPLETION_COMPAT_DIR" ]; then
中的行/opt/local/etc/bash_completion
。我终于找到了问题,因为我export PS1='>'
中有.bash_profile
这个问题。将PS1更改为其他内容(例如'> '
)可以解决bash完成问题。
在OS X和Debian中进行的一些实验表明,在涉及{{1}的表达式后,在测试(-a
)中添加额外的表达式(-o
或[ ]
)时会出现此问题}}。如,
'>'
这是bash中的(已知)错误吗?
答案 0 :(得分:4)
只要$A
中存储的字符串不是[
/ test
识别的运算符,您的解决方法就有效了 - 只需添加空格即可就像你发现的那样充足。
当然,“大于”应该被解释为一个字符串?它适用于'> ' 毕竟。
不,$A
的内容不仅被解释为字符串。 (如果你想要的话,你必须使用[[
代替,它在特殊的上下文中解析,更像你对传统编程语言的期望。)
[
(test
)是内置函数(在大多数系统中也作为外部实用程序存在),因此使用命令语法进行解析,这意味着:
$A
引用将替换为变量的内容。[
因此,从[
的角度来看,它最终看到的运算符 - 在您的示例中是>
- 来自 literal 或者存储在变量。
但请注意空白很重要:传递>
(无空格)被解释为运算符;相比之下,>
不是><space>
- 因为确切的文字更多而不仅仅是操作符。
底线是:
-o
/ -a
以避免您遇到的歧义(强调我的):指定 -a和-o 二元原色和'('和')'运算符的XSI扩展名已标记为过时。 (根据所评估的特定表达式,语法中使用它们的许多表达式都是模糊定义。)
具体而言,使用与[ ... ]
(而非&&
)和-a
(而非||
)相结合的单独-o
表达式解决了问题:
[ -n "$BASH_VERSION" ] && [ -n "$PS1" ] && [ -z "$BASH_COMPLETION_COMPAT_DIR" ]
或者,更简单地说,利用非空字符串评估为true:
[ "$BASH_VERSION" ] && [ "$PS1" ] && [ -z "$BASH_COMPLETION_COMPAT_DIR" ]
请注意,虽然-a
和-o
会引入歧义,但他们不 安全问题 - 您不能通过使用注入任意代码。
答案 1 :(得分:2)
如果您想使用两个或更多条件,则应使用
if [ condition1 ] && [condition2 ]
或
if [ condition1 ] || [condition2 ]
所以在你的情况下(首先是“和”):
A='>'; if [ -n "$A" ] && [ -n "$A" ]; then echo "yes"; fi
表示“或”if:
A='>'; if [ -n "$A" ] || [ -n "Hello" ]; then echo "yes"; fi
但请注意,第二次检查[ -n "Hello" ]
始终为真,因此最好将其删除。
您可能会对shellcheck感兴趣,以验证您的bash脚本语法。