66

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

set +e; some-command; res=$?; set -e跳舞,我怎么能做到呢?

4

5 回答 5

93

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

这是规范的做法。

于 2013-09-04T19:54:43.437 回答
15

作为备选

ans=0
some-command || ans=$?
于 2013-09-04T19:52:22.027 回答
8

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

res=$(some-command > /dev/null; echo $?)
于 2013-09-04T19:42:45.753 回答
0

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

#!/bin/sh

set -e

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

echo $rc
于 2021-08-29T01:23:13.133 回答
-3

使用包装函数来执行您的命令:

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
...
于 2013-09-04T19:47:56.030 回答