繁体   English   中英

当“set -e”处于活动状态时,Bash 获取命令的退出状态?

[英]Bash get exit status of command when 'set -e' is active?

我通常在我的 Bash 脚本中设置-e ,但偶尔我想运行命令并获取返回值。

不做set +e; some-command; res=$?; set -e set +e; some-command; res=$?; set -e set +e; some-command; res=$?; set -e dance,我该怎么做?

bash手册中:

如果失败的命令是在&&或||中执行的任何命令的一部分,则shell不会退出 列出[...]。

因此,只需:

#!/bin/bash

set -eu

foo() {
  # exit code will be 0, 1, or 2
  return $(( RANDOM % 3 ))
}

ret=0
foo || ret=$?
echo "foo() exited with: $ret"

示例运行:

$ ./foo.sh
foo() exited with: 1
$ ./foo.sh
foo() exited with: 0
$ ./foo.sh
foo() exited with: 2

这是规范的做法。

作为备选

ans=0
some-command || ans=$?

也许尝试像这样在子外壳中运行有问题的命令?

res=$(some-command > /dev/null; echo $?)

鉴于此问题中描述的 shell 行为,可以使用以下构造:

#!/bin/sh

set -e

{ custom_command; rc=$?; } || :

echo $rc

另一种选择是使用简单的if 它有点长,但完全受 bash 支持,即该命令可以返回非零值,但即使使用set -e脚本也不会退出。 在这个简单的脚本中看到它:

#! /bin/bash -eu

f () {
  return 2
}

if f;then
  echo Command succeeded
else
  echo Command failed, returned: $?
fi
echo Script still continues.

当我们运行它时,我们可以看到脚本在非零返回码之后仍然继续:

$ ./test.sh 
Command failed, returned: 2
Script still continues.

使用包装函数执行命令:

function __e {
    set +e
    "$@"
    __r=$?
    set -e
}

__e yourcommand arg1 arg2

并使用$__r代替$?

if [[ __r -eq 0 ]]; then
    echo "success"
else
    echo "failed"
fi

调用管道中命令的另一种方法,只是您必须引用管道。 这样做很安全。

function __p {
    set +e
    local __A=() __I
    for (( __I = 1; __I <= $#; ++__I )); do
        if [[ "${!__I}" == '|' ]]; then
            __A+=('|')
        else
            __A+=("\"\$$__I\"")
        fi
    done
    eval "${__A[@]}"
    __r=$?
    set -e
}

例:

__p echo abc '|' grep abc

我实际上更喜欢这种语法:

__p echo abc :: grep abc

我可以做的

...
        if [[ ${!__I} == '::' ]]; then
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM