【问题标题】:How to return the error from a sourced bash script如何从源 bash 脚本返回错误
【发布时间】:2017-02-07 23:20:10
【问题描述】:

我对 bash 脚本还很陌生。我有 4 个嵌套的 bash 脚本,我无法从第 4 个脚本中适当地传播错误。例如:

script1.sh:
  source script2.sh
  <check for error and display appropriate message>
script2.sh:
  source script3.sh param_1
  <return to script1 on error>
  source script3.sh param_2
  <return to script1 on error>
  source script3.sh param_n
  <return to script1 on error>
script3.sh
  <some processing>
  script4.sh
  echo "this statement is not reached"
  return $?
script4.sh
  <some processing>
  exit $?

我的要求是:

  1. 我需要在script1 中定义一个关联数组,该数组填充在script2 中,并且在script3 范围内可用。我认为这样做的唯一方法是 source script2 和 script3
  2. script4 的执行不是源代码,因为该脚本也可以独立于这些父脚本执行

thread 谈到了使用 return 语句从源 bash 脚本返回,但是在执行 script4 时我需要退出。我不明白为什么 script4 中的 exit 语句会导致原始 shell 和子 shell 都终止?当然它应该只退出子shell?

我需要查看信号和陷阱吗?

感谢您的帮助

【问题讨论】:

  • 你说的是对的:子shell中的exit应该只退出那个子shell。也许set -x在你的shell中执行之前,并研究跟踪输出。
  • 获取文件本身并不会创建子shell,它所做的只是读取并执行源文件,就好像它在主脚本中一样。 return 从源文件返回,是一种特殊情况。 exit 终止进程。也许“子外壳”一词让您感到困惑?子shell 是执行当前shell 副本的子进程,通常通过将命令放在括号( ) 内来创建。我在您的代码中没有看到任何子 shell。
  • source 不会创建子外壳。它更像是其他语言中的包含语句。在当前 shell 中运行代码。如果您提供一些真实的代码,那么我们可以准确地解释发生了什么。
  • set -e 仅适用于那些有从不检查他们运行的任何命令的返回码的坏习惯的人的好习惯。只有当您确切知道它将如何影响您的脚本时,您才应该使用它。我从不使用它。
  • @crispo, ...re: set -e,见BashFAQ #105——这是否是一种好的做法是一个令人惊讶的争论。

标签: bash return-value


【解决方案1】:

您可以根据需要保持set -e 处于启用状态。然后,您必须更加小心地调用您知道退出状态可能为非零的脚本:

script3.sh
  <some processing>
  if script4.sh; then
    rc=0
  else
    rc=$?
  fi
  echo "script4 complete"
  return $rc

https://www.gnu.org/software/bash/manual/bashref.html#index-set

IMO,如果您真的想因任何错误而中止程序,则使用 set -e 是合适的。在这里,你想&lt;check for error and display appropriate message&gt;,显然不是这样。

【讨论】:

    【解决方案2】:

    最佳实践是明确的。如果您的代码总是被获取,因此return 将是有效的,那么简单::

    source foo || return
    

    return 使用前一条命令的退出状态作为默认值,因此无需捕获然后传递。


    如果你不知道你是否会被寻找或处决,这会变得有点复杂:

    source foo || { rc=$?; return "$rc" 2>/dev/null || exit "$rc" }
    

    【讨论】:

      猜你喜欢
      • 2011-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      相关资源
      最近更新 更多