启动新 shell 时停止从函数内获取脚本或继承环境的任何方法

启动新 shell 时停止从函数内获取脚本或继承环境的任何方法

已编辑以澄清

我有一个通常应该执行的脚本。但是,出于测试目的,我希望能够获取它以获取所有函数和变量的定义,并根据需要设置环境并创建目录,然后在重要部分开始之前返回。基本上,我需要获得一个与环境交互的 shell,因为它会在执行一些检查后进行处理,但前提是所有检查都通过。

代码流程如下所示:

#!/bin/bash

SOME_VAR="hey"
checker() {
  # can find fatal conditions which should exit the script
  # or stop sourcing it
  # ... do some checks
  # if all OK
  return 0

  # otherwise stop
  if [ "${0}" != "${BASH_SOURCE[0]}" ] ; then
    : #!!!! we're being sourced, what to do here??
  fi
  exit 1
}

# some more function definitions...

# do some checks to see if the current environment is supported
checker "some_fatal_condition" # need to stop sourcing here
checker "some_other_condition"

# if the script is being sourced for testing purposes, 
# and all ok up to here, stop now
return 2>/dev/null

# actual stuff follows, only if executing
# ...

我的问题是,当采购它时,如何停止处理源脚本而不从函数内部退出 shell 函数 checker

我应该补充一点,做类似的事情

checker "some_fatal_condition" || return 2>/dev/null

在这种情况下不是一个选项(还有更多函数可能需要退出并且可能从其他函数调用,等等)。

关于如何实现我想要的目标而不从我的主 shell 会话中获取它,我想到了一些事情。

  • 建议 1:从我的 shell 中启动一个嵌套 shell,并在其中获取脚本。这样,如果脚本在获取源时退出,就不是什么大问题了。

  • 建议 2:不允许获取脚本,而是传递一个命令行选项,告诉它“这只是测试”,并在我需要的地方启动交互式 shell。然后在重要部分之前退出脚本。

建议2的问题是我不知道如何从继承所有定义的变量、函数、shell 选项的脚本中启动交互式 shell等等...我该怎么做?

答案1

您不应该exit从函数内部进行操作,除非它明确是错误/退出处理程序。最好是return来自一个函数。

将函数与脚本主体分开的另一种方法就是这样做:将函数放入单独的文件中,并将其源到脚本中。

答案2

好的,我找到了如何自动导出变量,以便我可以启动交互式 shell 进行测试:set -a在脚本顶部。

#!/bin/bash

if [ "${0}" != "${BASH_SOURCE[0]}" ] ; then
  echo "This script should not be sourced" >&2
  return 1
fi

set -a # automatically export all vars
SOME_VAR="hey"
checker() {
  # can find fatal conditions which should exit the script
  # or stop sourcing it
  # ... do some checks
  # if all OK
  return 0

  # otherwise stop
  exit 1
}

# some more function definitions...

# do some checks to see if the current environment is supported
checker "some_fatal_condition" # need to stop sourcing here
checker "some_other_condition"

# if the script is being sourced for testing purposes, stop now
if [ "${1}" == "test" ] ; then
  PS1="test> " bash
  exit $?
fi

echo "proceeding"
# actual stuff follows, only if executing
# ...

相关内容