具有OR条件的shell脚本中的字符串比较

具有OR条件的shell脚本中的字符串比较,shell,Shell,我已经编写了以下shell脚本 if [ "$LOCALE" == "US" ] then #do something elif [ "$LOCALE" == "DE" || "$LOCALE" == "FR" || "$LOCALE" == "IT" || "$LOCALE" == "UK" ] then #do something else. fi 它给了我一个错误[:missing]。有人能解释一下这里的错误吗?在[…]中,使用-a(和)和-o(或): 在[…]]内部,您

我已经编写了以下shell脚本

if [ "$LOCALE" == "US" ]
then
   #do something

elif [ "$LOCALE" == "DE" || "$LOCALE" == "FR" || "$LOCALE" == "IT" || "$LOCALE" == "UK" ]
then
   #do something else.
fi

它给了我一个错误
[:missing]
。有人能解释一下这里的错误吗?

[…]
中,使用
-a
(和)和
-o
(或):



[…]]
内部,您可以使用
&&
(和)和
|
(或)。

内部
[…]
,使用
-a
(和)和
-o
(或):



[…]]
内部,您可以使用
&&
(和)和
|
(或)。

内部
[…]
,使用
-a
(和)和
-o
(或):



[…]]
内部,您可以使用
&&
(和)和
|
(或)。

内部
[…]
,使用
-a
(和)和
-o
(或):



[…]]
内部,您可以使用
&&
(and)和
|
(or)。

如果运行命令(或者更严格地说,如本例中的“管道”),则shell的

命令的退出状态决定
然后
部件是否运行(或
否则
部件,如果有)。如果管道“成功”,即,如果文件至少部分命名为
xyzy
,“然后”部分运行,那么管道将退出零

[
命令…是一个命令!(它内置于所有现代shell变体中以提高速度,但可以作为普通命令运行。)

[
命令读取参数并要求它们以
]
结尾:

sh-3.2$ [
sh: [: missing `]'
sh-3.2$
这是您遇到的错误,因为在
sh
语法中,
prog1 | | prog2
意味着首先运行
prog1
,然后只有在它“失败”(退出非零)时,才运行
prog2
。因此:

prog1 arg || grep xyzzy somefile
仅当
prog1
失败时才运行
grep
。因此,依次:

[ x || grep xyzzy somefile
如果
[
失败(由于语法错误),则运行
grep

(旁白:我经常看到人们写这样的东西:

ls | grep xyzzy
if [ $? = 0 ]; then cmd1; cmd2; cmd3; fi
这是不必要的长篇大论,因为
$?
只是最后一个管道的退出状态,所以这与我的第一个示例相同。当然,有些人可能会说这个stackoverflow答案也不必要的长篇大论。:-)

要使
[
程序测试多个条件,可以使用其
-a
(“and”)和
-o
(“or”)运算符。然后,所有测试都将通过运行
[
程序完成:

if [ "$LOCALE" == DE -o "$LOCALE" == FR ]; then ...; fi
或者,使用
[
程序的多次调用,但这在这里变得更加困难,并且开始需要括号或方括号:

([ "$LOCALE" == DE ] || [ "$LOCALE" == FR ]) && (cmd1; cmd2; ...)

{ [ "$LOCALE" == DE ] || [ "$LOCALE" == FR ]; } && { cmd1; cmd2; ...; }

if { [ "$LOCALE" == DE ] || [ "$LOCALE" == FR ]; } then cmd1; cmd2; ... fi
(我不推荐这些替代方案:它们有效,但不必要地难以阅读。如果必须使用,最后一种可能是最不可怕的。)

考虑将所有这些替换为
案例

case "$LOCALE" in
DE|FR|IT|UK) cmd1; cmd2; cmd3;;
*) other commands here;;
esac
case
语句提供全局式匹配。例如,您可以将用户答案与大小写混合匹配:

need_answer=true
while $need_answer; do
    echo -n "should I do a thing? (yes/no, default = no) "
    read answer
    case "$answer" in
    [yY]|[yY][eE]|[yY][eE][sS])
        # handle "yes" case here
        need_answer=false;;
    [nN]|[nN][oO]|"")
        # handle "no" case here
        need_answer=false;;
        ;;
    *) echo "please answer yes or no";;
    esac
done
*
通过glob匹配之前未匹配的任何输入来工作,因为各种情况是线性的,第一次匹配“获胜”



一些shell(bash尤其值得注意)有额外的可选语法可用于
if
语句。

shell的
if
运行命令(或者更严格地说,是“管道”,如本例所示):

该命令的退出状态确定
然后
部分是否运行(或
否则
部分,如果有)。如果管道“成功”,即,如果文件至少部分命名为
xyzy
,则退出零-“然后”部分运行

[
命令…是一个命令!(它内置于所有现代shell变体中以提高速度,但可以作为普通命令运行。)

[
命令读取参数并要求它们以
]
结尾:

sh-3.2$ [
sh: [: missing `]'
sh-3.2$
这是您遇到的错误,因为在
sh
语法中,
prog1 | | prog2
意味着首先运行
prog1
,然后只有在它“失败”(退出非零)时,才运行
prog2
。因此:

prog1 arg || grep xyzzy somefile
仅当
prog1
失败时才运行
grep
。因此,依次:

[ x || grep xyzzy somefile
如果
[
失败(由于语法错误),则运行
grep

(旁白:我经常看到人们写这样的东西:

ls | grep xyzzy
if [ $? = 0 ]; then cmd1; cmd2; cmd3; fi
这是不必要的长篇大论,因为
$?
只是最后一个管道的退出状态,所以这与我的第一个示例相同。当然,有些人可能会说这个stackoverflow答案也不必要的长篇大论。:-)

要使
[
程序测试多个条件,可以使用其
-a
(“and”)和
-o
(“or”)运算符。然后,所有测试都将通过运行
[
程序完成:

if [ "$LOCALE" == DE -o "$LOCALE" == FR ]; then ...; fi
或者,使用
[
程序的多次调用,但这在这里变得更加困难,并且开始需要括号或方括号:

([ "$LOCALE" == DE ] || [ "$LOCALE" == FR ]) && (cmd1; cmd2; ...)

{ [ "$LOCALE" == DE ] || [ "$LOCALE" == FR ]; } && { cmd1; cmd2; ...; }

if { [ "$LOCALE" == DE ] || [ "$LOCALE" == FR ]; } then cmd1; cmd2; ... fi
(我不推荐这些替代方案:它们有效,但不必要地难以阅读。如果必须使用,最后一种可能是最不可怕的。)

考虑将所有这些替换为
案例

case "$LOCALE" in
DE|FR|IT|UK) cmd1; cmd2; cmd3;;
*) other commands here;;
esac
case
语句提供全局式匹配。例如,您可以将用户答案与大小写混合匹配:

need_answer=true
while $need_answer; do
    echo -n "should I do a thing? (yes/no, default = no) "
    read answer
    case "$answer" in
    [yY]|[yY][eE]|[yY][eE][sS])
        # handle "yes" case here
        need_answer=false;;
    [nN]|[nN][oO]|"")
        # handle "no" case here
        need_answer=false;;
        ;;
    *) echo "please answer yes or no";;
    esac
done
*
通过glob匹配之前未匹配的任何输入来工作,因为各种情况是线性的,第一次匹配“获胜”



一些shell(bash尤其值得注意)有额外的可选语法可用于
if
语句。

shell的
if
运行命令(或者更严格地说,是“管道”,如本例所示):

该命令的退出状态决定
然后
部分是否运行(或
否则
部分,如果有)。如果管道“成功”,即,如果