这适用于 shell(bash、dash)提示符:
[ -z "" ] && echo A || echo B
A
不过,我正在尝试写一个POSIXshell脚本,它的开头是这样的:
#!/bin/sh
[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1
readonly raw_input_string=${1}
[ -z "${raw_input_string}" ] && echo "The given argument is empty."; exit 1
我不知道为什么,但我没有收到消息:
给定的参数为空。
如果我这样调用脚本:
./test_empty_argument ""
这是为什么?
答案1
请注意您的线路
[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1
这与
[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."
exit 1
(;
在大多数情况下,不带引号的可以替换为换行符)
这意味着exit 1
无论向脚本传递了多少参数,该语句始终都会执行。这反过来意味着该消息The given argument is empty.
永远没有机会被打印。
要使用“短路语法”在测试后执行多个语句,请将语句分组在{ ...; }
.另一种方法是使用正确的if
语句(恕我直言,它在脚本中看起来更干净):
if [ "$#" -ne 1 ]; then
echo 'Invalid number of arguments, expected one.' >&2
exit 1
fi
你的第二次测试也有同样的问题。
关于
[ -z "" ] && echo A || echo B
这适用于给定的示例,但通用
some-test && command1 || command2
会不是与
if some-test; then
command1
else
command2
fi
相反,它更像是
if ! { some-test && command1; }; then
command2
fi
或者
if some-test && command1; then
:
else
command2
fi
也就是说,如果测试或第一个命令失败,则执行第二个命令,这意味着它有可能执行三个全部涉及的言论。
答案2
这:
[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1
不是:
[ "${#}" -eq 1 ] || { echo "Invalid number of arguments, expected one."; exit 1; }
但相反的是:
{ [ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; }
exit 1
无论您向脚本传递了多少参数,脚本都会退出。
答案3
使其更具可读性的一种方法是定义一个die
函数(à la perl
),例如:
die() {
printf >&2 '%s\n' "$@"
exit 1
}
# then:
[ "$#" -eq 1 ] || die "Expected one argument, got $#"
[ -n "$1" ] || die "Empty argument not supported"
如果需要,您可以添加更多附加功能,例如颜色、前缀、行号...。
答案4
我经常将其视为空字符串的测试:
if [ "x$foo" = "x" ]; then ...