31

我想从在另一个脚本中调用的 BASH 脚本返回退出代码,但也可以直接调用。它大致看起来像这样:

#!/bin/bash
dq2-get $1
if [ $? -ne 0 ]; then
  echo "ERROR: ..."
  # EXIT HERE
fi
# extract, do some stuff
# ...

现在在该行EXIT HERE脚本应该退出并返回退出代码 1。问题是

  • 我不能使用return,因为当我忘记获取脚本而不是调用它时, return不会退出,脚本的其余部分将被执行并搞砸。
  • 我不能使用exit,因为这会关闭外壳。
  • 我不能使用好技巧kill -SIGINT $$,因为这不允许返回退出代码。

有没有我忽略的可行替代方案?

4

5 回答 5

19

问题标题的答案(不像其他答案那样在正文中)是:

在不关闭 shell 的情况下返回退出代码

(exit 33)

如果您需要-e激活并且仍然避免使用非零退出代码退出 shell,请执行以下操作:

(exit 33) && true

true命令从不执行,但用于构建不被-eshell 标志退出的复合命令。

这会设置退出代码而不退出 shell(也不是源脚本)。

对于更复杂的退出问题(使用特定的退出代码),无论是执行还是获取:

#!/bin/bash
[ "$BASH_SOURCE" == "$0" ] &&
    echo "This file is meant to be sourced, not executed" && 
        exit 30

return 88

如果执行,将设置退出代码 30(带有错误消息)。
如果有来源,退出代码为 88。将退出执行或采购而不影响调用外壳

于 2018-11-23T23:58:35.020 回答
10

使用它而不是退出或返回:

[ $PS1 ] && return || exit;

无论来源与否都有效。

于 2014-01-24T23:03:10.547 回答
8

您可以使用x"${BASH_SOURCE[0]}" == x"$0"来测试脚本是否被来源或调用(如果来源为假,如果被调用,则为真)和return/或exit相应地。

于 2011-05-24T15:07:56.310 回答
1

另一种选择是使用一个函数并将返回值放入其中,然后简单地获取脚本(source processStatus.sh)或调用脚本(./processStatus.sh)。例如,考虑 processStatus.sh 脚本,它需要向 stopProcess.sh 脚本返回一个值,但还需要在不使用源代码的情况下与命令行分开调用(仅包括相关部分)例如:

check_process ()
{
  if [ $1 -eq "50" ]
  then
    return 1       
  else
    return 0
  fi       
}

source processStatus.sh $1
RET_VALUE=$?
if [ $RET_VALUE -ne "0" ]
then
  exit 0
fi
于 2015-01-02T09:18:13.097 回答
0

return如果您在脚本的开头使用,则可以使用。set -e

如果您只想检查函数是否没有返回错误,我宁愿建议像这样重写您的代码:

#!/bin/bash

set -e # exit program if encountered errors

dq2-get ()
{
  # define the function here
  # ...
  if [ $1 -eq 0 ]
  then
    return 0
  else
    return 255
  # Note that nothing will execute from this point on,
  # because `return` terminates the function.
}

# ...
# lots of code ...
# ...

# Now, the test:
# This won't exit the program.
if $(dq2-get $1); then
  echo "No errors, everything's fine"
else
  echo "ERROR: ..."
fi
# These commands execute anyway, no matter what
# `dq2-get $1` returns (i.e. {0..255}).
# extract, do some stuff
# ...

dq2-get $1现在,如果函数返回错误,上面的代码将不会离开程序。但是,由于set -e. 下面的代码描述了这种情况:

# The function below will stop the program and exit
# if it returns anything other than `0`
# since `set -e` means stop if encountered any errors.
$(dq2-get $1)
# These commands execute ONLY if `dq2-get $1` returns `0`
# extract, do some stuff
# ...
于 2020-04-24T07:51:52.187 回答