如何使用case语句处理多个返回值

Pau*_*tos 1 bash case exit-status

看看这些尝试:

$ case `true` in 0) echo success ;; *) echo fail ;; esac
fail
$ if `true` ; then
> echo "success"
> else 
> echo "fail"
> fi
success
Run Code Online (Sandbox Code Playgroud)

现在,为什么 case 语句失败了?你可能想知道为什么我不只使用这个if语句,我会解释一下。我的命令很复杂,可能会返回不同的返回码,我想对其采取行动。我不想多次运行命令,我不能这样做:

my_command
res = $?
case $? in
...
esac
Run Code Online (Sandbox Code Playgroud)

这是因为我set -e在我的脚本中使用,因此如果my_command返回失败脚本将中止。

但我有一个解决方法......

set +e
my_command
res=$?
set -e
case $? in 
...
esac
Run Code Online (Sandbox Code Playgroud)

但这很难看,所以回到我最初的问题......为什么我只能使用该case my_command in ... esac版本?

Kus*_*nda 6

你不能用

case $(somecommand) in ...
Run Code Online (Sandbox Code Playgroud)

测试退出状态,somecommand因为命令替换扩展到命令的输出,而不是其退出状态。

使用$(true)不起作用,因为true不会在标准输出上产生任何输出。

你可以做

case $(somecommand) in ...
Run Code Online (Sandbox Code Playgroud)

这将阻止在errexit( -e)下运行的脚本退出。

来自bash手册(来自 的描述set -e):

如果失败的命令是紧跟在 while 或 until 关键字之后的命令列表的一部分、在 if 或 elif 保留字之后的测试的一部分、在 && 或 || 中执行的任何命令的一部分,则 shell 不会退出 除了最后一个 && 或 || 之后的命令之外的列表 ,管道中除最后一个之外的任何命令,或者如果命令的返回值正在用 ! 反转。

在这种情况下,只有成功或失败的可能性,这样做会更容易

{ somecommand; err="$?"; } || true

case $err in
    0) echo success ;;
    *) echo fail
esac
Run Code Online (Sandbox Code Playgroud)


Bar*_*mar 5

语法

`command`
Run Code Online (Sandbox Code Playgroud)

表示将命令的标准输出替换为原始命令行。输出与退出状态不同。该true命令不产生任何输出,因此您的命令等效于:

case "" in
0) echo success ;;
*) echo fail ;;
esac
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式解决您的问题:

case `my_command; echo $?` in 
...
esac
Run Code Online (Sandbox Code Playgroud)

顺便说一句,在if您不需要反引号的命令中,它应该是:

if true
then echo successs
else echo fail
fi
Run Code Online (Sandbox Code Playgroud)