返回退出代码而不关闭 shell

发布于 2024-11-09 02:57:21 字数 483 浏览 0 评论 0原文

我想从在另一个脚本中调用的 BASH 脚本返回退出代码,但也可以直接调用。它大致如下所示:

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

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

  • 我无法使用 return,因为当我忘记获取脚本而不是调用它,返回将不会退出,并且脚本的其余部分将被执行并弄乱事情。
  • 我无法使用 exit,因为这会关闭 shell。
  • 我不能使用很好的技巧 kill -SIGINT $$,因为这不允许返回退出代码。

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

I'd like to return an exit code from a BASH script that is called within another script, but could also be called directly. It roughly looks like this:

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

Now in the line EXIT HERE the script should exit and return exit code 1. The problem is that

  • I cannot use return, because when I forget to source the script instead of calling it, return will not exit, and the rest of the script will be executed and mess things up.
  • I cannot use exit, because this closes the shell.
  • I cannot use the nice trick kill -SIGINT $$, because this doesn't allow to return an exit code.

Is there any viable alternative that I have overlooked?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

も星光 2024-11-16 02:57:21

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

返回退出代码而不关闭 shell

(exit 33)

如果您需要激活 -e 并且仍避免以非零退出代码退出 shell,则执行:

(exit 33) && true

true 命令是从未执行,但用于构建不由 -e shell 标志退出的复合命令。

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

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

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

return 88

如果执行,将设置退出代码 30(带有错误消息)。
如果已获取,则退出代码为 88。
将退出执行或采购两者,而不影响调用 shell。

The answer to the question title (not in the body as other answers have addressed) is:

Return an exit code without closing shell

(exit 33)

If you need to have -e active and still avoid exiting the shell with a non-zero exit code, then do:

(exit 33) && true

The true command is never executed but is used to build a compound command that is not exited by the -e shell flag.

That sets the exit code without exiting the shell (nor a sourced script).

For the more complex question of exiting (with an specific exit code) either if executed or sourced:

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

return 88

Will set an exit code of 30 (with an error message) if executed.
And an exit code of 88 if sourced.
Will exit both the execution or the sourcing without affecting the calling shell.

方觉久 2024-11-16 02:57:21

使用它代替退出或返回:

[ $PS1 ] && return || exit;

无论是否有来源都有效。

Use this instead of exit or return:

[ $PS1 ] && return || exit;

Works whether sourced or not.

紫轩蝶泪 2024-11-16 02:57:21

您可以使用 x"${BASH_SOURCE[0]}" == x"$0" 来测试脚本是否已获取或调用(如果已获取则为 false,如果已调用则为 true)并返回< /code> 或相应地退出

You can use x"${BASH_SOURCE[0]}" == x"$0" to test if the script was sourced or called (false if sourced, true if called) and return or exit accordingly.

南城旧梦 2024-11-16 02:57:21

另一种选择是使用函数并将返回值放入其中,然后简单地获取脚本 (source processStatus.sh) 或调用脚本 (./processStatus.sh) 。例如,考虑需要向 stopProcess.sh 脚本返回值的 processStatus.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

Another option is to use a function and put the return values in that and then simply either source the script (source processStatus.sh) or call the script (./processStatus.sh) . For example consider the processStatus.sh script that needs to return a value to the stopProcess.sh script but also needs to be called separately from say the command line without using source (only relevant parts included)
Eg:

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

and

source processStatus.sh $1
RET_VALUE=$?
if [ "$RET_VALUE" -ne "0" ]
then
  exit 0
fi
○闲身 2024-11-16 02:57:21

如果您在脚本开头使用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
# ...

You can use return if you use set -e in the beginning of the script.

If you just want to check if the function returned no errors, I'd rather suggest rewriting your code like this:

#!/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
# ...

Now, the code above won't leave the program if the function dq2-get $1 returns errors. But, implementing the function all by itself will exit the program because of the set -e. The code below describes this situation:

# 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
# ...
七堇年 2024-11-16 02:57:21

感谢您的提问,我的情况是source一个文件进行某些设置,但如果不满足某些条件,则结束脚本并跳过设置操作。

我遇到了尝试使用 exit() 的问题,实际上导致了我的终端关闭,并发现自己在这里:D

在查看了特定解决方案的选项后,我只是选择了如下所示的内容,我还认为如果这种方法适用于您的情况,Deepaks 答案值得审查。

if [ -z "$REQUIRED_VAR" ]; then
  echo "please check/set \$REQUIRED_VAR ..."
  echo "skipping logic"
else
  echo "starting logic"
  doStuff()
  echo "completed logic"
fi

Thanks for the question, my case was to source a file for some setup, but end the script and skip the setup actions if certain conditions were not met.

I had hit the issue of an attempt to use exit() actually causing the closing of my terminal, and found myself here :D

After reviewing the options for the specific solution i just went with something like the below, I also think Deepaks answer is worth reviewing if this approach works in your case.

if [ -z "$REQUIRED_VAR" ]; then
  echo "please check/set \$REQUIRED_VAR ..."
  echo "skipping logic"
else
  echo "starting logic"
  doStuff()
  echo "completed logic"
fi
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文