d3p*_*3pd 5 bash return exit terminate
我有一个源代码的Bash脚本.当这个脚本来源时,它在Bash脚本中运行一个函数.如果匹配某个条件,此函数应终止脚本.如何在不终止脚本所在的shell的情况下完成此操作?
要明确:我希望终止操作由源shell脚本中的函数完成,而不是在源shell脚本的主体中完成.我可以看到的问题是,return
在exit 1
终止调用shell时,只需从函数返回到脚本的main .
以下最小示例说明了此问题:
main(){
echo "starting test of environment..."
ensure_environment
echo "environment safe -- starting other procedures..."
}
ensure_environment(){
if [ 1 == 1 ]; then
echo "environment problemm -- terminating..."
# exit 1 # <-- terminates calling shell
return # <-- returns only from function, not from sourced script
fi
}
main
Run Code Online (Sandbox Code Playgroud)
您可以return
从源shell脚本中获取.POSIX规范
所以,虽然你不能return
直接从函数中得到你想要的东西,但如果你的函数返回非零(或其他一些约定的值),你可以从脚本的主体返回.
例如:
$ cat foo.sh
f() {
echo in f "$@"
}
e() {
return 2
}
f 1
e
f 2
if ! e; then
return
fi
f 3
$ . foo.sh
in f 1
in f 2
Run Code Online (Sandbox Code Playgroud)
这是一个如何通过你的方法实现你的目标的秘诀。我不会为您编写代码,只是描述如何完成它。
您的目标是通过有效地获取可能复杂的 shell 脚本来设置/更改当前 bash shell 中的环境变量。该脚本的某些组件可能会决定应停止执行该源脚本。使事情变得复杂的是,这个决定不一定是顶层的,但可能位于嵌套函数调用中。return
,那么,没有帮助,并且exit
会终止采购 shell,这是不希望的。
您的以下声明使您的任务变得更加容易:
我无法在一个最小的示例中真正包含额外的复杂性,因此非常需要将终止过程集中在函数中。
您可以这样做:
您不是采购真正的脚本来决定将哪个环境设置为什么(“ realscript.bash
”),而是采购另一个脚本“ ipcscript.bash
”。
ipcscript.bash
将设置一些进程间通信。这可能是您使用 exec 打开的某个额外文件描述符上的管道,它可能是临时文件,也可能是其他文件。
ipcscript.bash
然后将realscript.bash
作为子进程启动。这意味着,首先发生的环境更改realscript.bash
只会影响 bash 子进程实例的环境。作为子进程启动realscript.bash
,您可以获得在任何嵌套级别通过 exit 终止执行的能力,而无需终止源 shell。
正如您所写,您对 exit 的调用将存在于一个集中函数中,当决定终止执行时,该函数会从任何级别调用。您的终止函数现在需要在退出之前以合适的格式将当前环境写入 IPC 机制。
ipcscript.bash
将从IPC机制中读取环境设置并在采购shell过程中重现所有设置。