我试图编写一个简短的bash脚本,可以选择接受来自命令行的参数,或提示输入
if [ [ -z "$message" ] && [ -z "$predefined" ] ] ; then
read -p "Enter message [$defaultMessage]: " message
message=${message:-$defaultMessage}
else
if [ -n "$predefined" ]; then
if [ -f $base/$environment/vle/data/$predefined.txt ]; then
echo Predefined message file $predefined.txt does not exist
exit 1
fi
fi
fi
如果message
和predefined
都没有作为命令行参数传入,那么代码应该提示message
的值;否则,如果predefined
已作为命令行参数传入,则脚本应测试是否存在该名称的文件,并且仅在文件存在时才继续
但我收到以下错误
[: -z: binary operator expected
在if
次测试中的第一次
帮助解释我的第一个if
语句的语法有什么问题?或者提供替代语法来实现相同的目标。
答案 0 :(得分:5)
第一个if
格式不正确。这可行:
if [ -z "$message" ] && [ -z "$predefined" ]; then
或者这个:
if test -z "$message" && test -z "$predefined"; then
或者这种特定于bash的,简单但又脏的方式:
if [[ -z "$message" ]] && [[ -z "$predefined" ]]; then
或这种特定于bash的正确方式:
if [[ -z $message && -z $predefined ]]; then
在最后一个版本中,双引号是不必要的,而不是拼写错误。
感谢@mklement0更改了特定于bash的样式以及最终评论:
我应该注意到,在
[[ ... ]]
内仍然需要双引号的情况,即如果你想在字符串比较的右侧有一个变量引用(==
)被视为文字:v='[a]' [[ $v == $v ]] # FALSE! [[ $v == "$v" ]] # true
如果没有双引号,右侧将被解释为模式。有些人主张总是双引用变量引用,以便不必记住这些细微之处。也就是说(从bash 3.2开始),当正则表达式与
=~
匹配时,你不得双引右操作数
答案 1 :(得分:1)
test expression1 -a expression2
如果两个表达式都为真,则为真。
test expression1 -o expression2
如果其中一个或两个表达式都为真,则为真。
if [ -z "$message" -a -z "$predefined" ]; then
read -p "Enter message [$defaultMessage]: " message
message=${message:-$defaultMessage}
else
if [ -n "$predefined" -a -f $base/$environment/vle/data/$predefined.txt ]; then
echo Predefined message file $predefined.txt does not exist
exit 1
fi
fi
这可以将4个测试组合成2个,同时还可以删除一个嵌套的if表达式;然后 ; fi