shell 如何获取倒数第二个命令的退出状态?

q43xntqr  于 2023-01-05  发布在  Shell
关注(0)|答案(3)|浏览(207)

我想运行两个命令,输出第一个命令的退出状态。所有这些,我想在一行命令中完成。

cmd1; cmd2 && echo $?-1

它应该输出cmd1的退出状态。

k4aesqcs

k4aesqcs1#

与任何其他状态随时间更新的全局变量一样(例如,C语言中的errno),如果要引用旧值,需要提前存储它。

cmd1; cmd1_retval=$?; cmd2 && echo "$cmd1_retval"

顺便说一句,不同之处在于管道:

cmd1 | cmd2 | cmd3
echo "${PIPESTATUS[$(( ${#PIPESTATUS[@]} - 2 ))]}"

这是因为在管道中,所有组件同时运行,退出状态默认为最后一个组件的退出状态,而在bash中,所有组件的退出状态存储在PIPESTATUS数组中; ${#PIPESTATUS[@]}获取此数组的长度,并从中减去2(一个是因为基于0和基于1的索引之间的差异,另一个是从最后一个项到倒数第二个项),得到前一管道中倒数第二个项。

k0pti3hp

k0pti3hp2#

cmd1; status=$?; cmd2 && echo $status
fkvaft9z

fkvaft9z3#

如果您有两个命令,如下所示,您将检查第一个命令的版本,以查看是否安装了命令的正确版本:

#!/usr/bin/env bash

set -e

cmd1="my_command version"
cmd2="sleep 1"
exit_code=$(${cmd1}; status=$?; ${cmd2} && echo $status)
printf "_${exit_code}_"

if [[ "_${exit_code}_" == "_0_" && "$(my_command version)" =~ " 1." ]]; then
   my_command
fi

如果versionmy_command的有效选项或命令,则输出可能如下所示,其中my_command 1.0.0my_command version的输出,0是结尾处的退出代码。注意,我使用了用_括起来的值,只是为了使它更清楚:

_my_command 1.0.0
0_

这将不满足if语句的第一个条件。
但是,如果当前安装的my_command版本是仅支持使用选项--version的不同版本,则输出可能如下所示,因此使用my_command version无效:

_1_

为了解决这个问题,我只是从last_char=${exit_code: -1}的最后一个字符获取退出代码,并将if语句的第一个条件改为"_${last_char}_" == "_0_"

#!/usr/bin/env bash

set -e

cmd1="my_command version"
cmd2="sleep 1"
exit_code=$(${cmd1}; status=$?; ${cmd2} && echo $status)
last_char=${exit_code: -1}
printf "_${last_char}_"

if [[ "_${last_char}_" == "_0_" && "$(my_command version)" =~ " 1." ]]; then
   my_command
fi

相关问题