繁体   English   中英

在 bash 中,退出脚本而不退出 shell 或从子外壳中导出/设置变量

[英]In bash, either exit script without exiting the shell or export/set variables from within subshell

我有一个 function 运行一组脚本,这些脚本在当前 shell 中设置变量、函数和别名。

reloadVariablesFromScript() {
  for script in "${scripts[@]}"; do
    . "$script"
  done
}

如果其中一个脚本有错误,我想退出脚本然后退出function,而不是杀死shell。

reloadVariablesFromScript() {
  for script in "${scripts[@]}"; do
    {(
      set -e
      . "$script"
    )}
    if [[ $? -ne 0 ]]; then
      >&2 echo $script failed.  Skipping remaining scripts.
      return 1
    fi
  done
}

这会做我想要的,除了它不会在脚本中设置变量,无论脚本是成功还是失败。

如果没有子shell, set -e会导致整个 shell 退出,这是不可取的。

有没有一种方法可以防止被调用的脚本继续出错而不杀死 shell 或从子外壳中设置/导出变量、别名和函数?

以下脚本模拟了我的问题:

test() {
  {(
    set -e

    export foo=bar
    false
    echo Should not have gotten here!
    export bar=baz
  )}

  local errorCode=$?

  echo foo="'$foo'".  It should equal 'bar'.
  echo bar="'$bar'".  It should not be set.

  if [[ $errorCode -ne 0 ]]; then
    echo Script failed correctly.  Exiting function.
    return 1
  fi

  echo Should not have gotten here!
}

test

如果最坏的情况变得更糟,因为这些脚本实际上并不编辑文件系统,我可以在子 shell 中运行每个脚本,检查退出代码,如果成功,则在子 shell 之外运行它。

请注意, set -e有许多令人惊讶的行为——依赖它并不是普遍认为的好主意。 不过需要注意的是:我们可以将环境变量、别名和 shell 函数作为文本输出:

envTest() {
  local errorCode newVars
  newVars=$(
    set -e

    {
      export foo=bar
      false
      echo Should not have gotten here!
      export bar=baz
    } >&2

    # print generate code which, when eval'd, recreates our functions and variables
    declare -p | egrep -v '^declare -[^[:space:]]*r'
    declare -f
    alias -p
  ); errorCode=$?
  if (( errorCode == 0 )); then
    eval "$newVars"
  fi
 
  printf 'foo=%q. It should equal %q\n' "$foo" "bar"
  printf 'bar=%q. It should not be set.\n' "$bar"
 
  if [[ $errorCode -ne 0 ]]; then
    echo 'Script failed correctly.  Exiting function.'
    return 1
  fi
 
  echo 'Should not have gotten here!'
}
 
envTest

请注意,此代码仅在整个脚本段成功时评估export 问题文本和评论似乎表明如果不需要,这是可以接受的。

暂无
暂无

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

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