Shell中复杂条件的语法是什么?


11

如果要在shell(sh)中表示以下测试:

if ( a == 1 && ( b == 1 || b == 2 )) { ... }

到目前为止,我能写的最好的是:

if [[ $a -eq 1 ]]; then
  if [[ $b -eq 1 || $b -eq 2 ]]; then
     ...
  fi
fi

我不知道如何复合&&和|| 具有正确的优先级。谷歌搜索没有给我任何答案(教程仅提供基本示例,如果有的话)

将这两个if合并为一个的语法是什么?


1
有什么理由不使用ksh?那么您的初始代码将只需要一对括号即可:if (( a == 1 && ( b == 1 || b == 2 ))); then :; fi
manatwork 2012年

Answers:


15

请注意,[[ ]]它不在Bourne或POSIX中sh。对于真正的sh语法,有几种方法可以做到这一点。

仅使用一[ ]

if [ 1 -eq "$a" -a \( 1 -eq "$b" -o 2 -eq "$b" \) ]; then
    # ...
fi

避免使用POSIX -a-o选项1

if [ 1 -eq "$a" ] && { [ 1 -eq "$b" ] || [ 2 -eq "$b" ]; }; then
    # ...
fi

1个一个原因,避免-a-o最大便携性-不是所有test[实现可以处理超过4个参数,而这恰恰是如果您将表达式与你所得到的-a-o\( \)


我的脚本有#!/ bin / sh shebang,默认外壳为ksh。为什么不使用?
Offirmo 2012年

2
@Offirmo如果将脚本声明为/bin/sh,则使用no​​t中的功能编写脚本是不正确的sh。您应该意识到,这ksh不是sh,而是的超集sh。如果将ksh-but-declared-as- shscript带到sh不是符号链接的系统,则ksh它可能会中断。您可以通过确保脚本与声明匹配来避免该问题。
jw013

我认为将/ bin / sh设置为shebang会使我的脚本通过/ bin / sh调用。您是说我的默认外壳程序(ksh)忽略了shebang并直接对其进行解释吗?
Offirmo 2012年

@Offirmo你是正确的:/bin/shwill 的shebang /bin/sh。问题是/bin/sh不接受[[。您不能使用也不能使用[[接受接受的shell [[,例如ksh作为shebang。
jw013

2
问题不在于某些实现不支持-a/ -o,但是对于任意参数来说并不可靠。就像[ "$a" = "$b" -o "$b" = "$c" ]将失败的值$a一样!有许多[的实现。
斯特凡Chazelas

2

我尝试了一些语法,发现

if [[ $a -eq 1 ]] && [[ $b -eq 1 || $b -eq 2 ]]; then
 ...
fi

正在工作。


1
这个工程对于bash版本以上4
尼基尔Mulley


0

仅需正确的方法即可shell

if test 1 -eq "$a" && test 1 -eq "$b" -o 2 -eq "$b"; then 
    ...
fi

说明:

test这里用作括号和-o逻辑或。如果您逻辑上且在“括号”内,则可以使用-a

可以在这里找到更多信息

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.