我已经对语句行为做了一些测试bash
if
,但我不确定我是否正确理解它们的输出原因。
以下是我从每个不同的语句输出中提出的原因if
,所有原因都正确吗?我也找不到答案行为之一如下所述。 bash 版本是 4.1.2。
#!/bin/bash
set -x
# behavior 1
if [ $anything ]; then
echo 'true 1'
fi
# result is false cause $anything will be translated by bash to an empty string, and in 'test' command, EXPRESSION omitted will be false
# behavior 2
if [ '' ];then
echo 'true 2'
fi
# result is false cause in 'test' command, EXPRESSION omitted will be false
# behavior 3
if [ 0 ]; then
echo 'true 3'
fi
# result is true cause 0 is a STRING and that is same with '-n STRING', since the length of string '0' is definitely nonzero, so it is true
# behavior 4
if [ ]; then
echo 'true 4'
fi
# result is false cause in 'test' command, EXPRESSION omitted will be false
# behavior 1a
if $anything; then
echo 'true 1a'
fi
# result is true. But I don't understand why since bash will translate $anything to an empty string, shouldn't this will result in syntax error ?
# behavior 2a
if ''; then
echo 'true 2a'
fi
# syntax error cause 'list' is empty and command can not be found
# behavior 3a
if 0; then
echo 'true 3a'
fi
# syntax error cause 'list' is 0 and there is no such command as 0
# behavior 4a
if ; then
echo 'true 4a'
fi
# syntax error cause list is empty
set +x
答案1
结果是真的。但我不明白为什么既然 bash 会将 $anything 转换为空字符串,这难道不会导致语法错误吗?
关闭,但没有饼干。有一个表达:$anything
。if ; then
是一个错误,因为 bash 无法解析它(因此:句法错误)。它期望那里有一个命令列表,然后得到一个;
。解析发生在变量扩展发生之前,因此if $anything; then
解析得很好。接下来发生什么?$anything
进行扩展、字段分割等工作。这会留下一个空的命令列表,这确实是事实。比较:
if "$anything"; then echo foo; fi
if $anything; then echo foo; fi
"$anything";
不是一个空命令列表,它具有发生在空字符串上的命令,与 相同if '';
。但未引用的内容"$anything"
会扩展为空。
$anything
如果仅包含 中存在的空白字符IFS
,或者包含$IFS
与任何文件不匹配且该选项打开的分隔的 glob 列表,情况也是如此 nullglob
。
答案2
语句中的括号[ "$foo" ]
是命令的一种简写test
,IE [ "$foo" ]
和test "$foo"
是等价的。
另一方面,只需输入空白或未设置的字符串,就会返回true
退出代码:
unset foo; $foo; echo $?
0
相比于:
unset foo ; test $foo ; echo $?
1