我有一个脚本,我不希望它调用退出,如果它是来源。
我想检查是否$0 == bash,但这有问题,如果脚本是从另一个脚本,或者如果用户从不同的shell,如ksh源。
是否有一种可靠的方法来检测脚本是否被引用?
我有一个脚本,我不希望它调用退出,如果它是来源。
我想检查是否$0 == bash,但这有问题,如果脚本是从另一个脚本,或者如果用户从不同的shell,如ksh源。
是否有一种可靠的方法来检测脚本是否被引用?
当前回答
检测Bash脚本是否正在执行或导入的最漂亮方法
我真的认为这是最美丽的方式:
从我的eRCaGuy_hello_world repo中的if__name__==__main__ check_if_sourced_or_executed_best.sh文件:
#!/usr/bin/env bash
main() {
echo "Running main."
# Add your main function code here
}
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
# This script is being run.
__name__="__main__"
else
# This script is being sourced.
__name__="__source__"
fi
# Only run `main` if this script is being **run**, NOT sourced (imported)
if [ "$__name__" = "__main__" ]; then
echo "This script is being run."
main
else
echo "This script is being sourced."
fi
引用:
关于上述技术的其他详细信息,请参见我在这里的另一个回答,包括显示运行输出:bash与Python的if __name__ == '__main__'等价于什么? 这个答案,我第一次了解到“${BASH_SOURCE[0]}”=“$0”
如果您愿意,还可以探索以下替代方案,但我更喜欢使用上面的代码块。
重要提示:使用“${FUNCNAME[-1]}”技术不能正确处理嵌套脚本,即一个脚本调用或来源另一个脚本,而if ["${BASH_SOURCE[0]}" = "$0"]技术可以。这是使用if ["${BASH_SOURCE[0]}" = "$0"]的另一个重要原因。
4种方法确定bash脚本是源脚本还是执行脚本
我已经阅读了关于这个问题和其他一些问题的一堆答案,并提出了4种我想要总结并放在一个地方的方法。
if __name__ == "__main__":
参见:如果__name__ == "__main__":会做什么?在Python中所做的事情。
You can see a full demonstration of all 4 techniques below in my check_if_sourced_or_executed.sh script in my eRCaGuy_hello_world repo. You can see one of the techniques in-use in my advanced bash program with help menu, argument parsing, main function, automatic execute vs source detection (akin to if __name__ == "__main__": in Python), etc, see my demo/template program in this list here. It is currently called argument_parsing__3_advanced__gen_prog_template.sh, but if that name changes in the future I'll update it in the list at the link just above
不管怎样,这里有4个Bash技术:
Technique 1 (can be placed anywhere; handles nested scripts): See: https://unix.stackexchange.com/questions/424492/how-to-define-a-shell-script-to-be-sourced-not-run/424495#424495 if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then echo " This script is being EXECUTED." run="true" else echo " This script is being SOURCED." fi Technique 2 [My favorite technique] (can be placed anywhere; handles nestes scripts): See this type of technique in-use in my most-advanced bash demo script yet, here: argument_parsing__3_advanced__gen_prog_template.sh, near the bottom. Modified from: What is the bash equivalent to Python's `if __name__ == '__main__'`? if [ "${BASH_SOURCE[0]}" == "$0" ]; then echo " This script is being EXECUTED." run="true" else echo " This script is being SOURCED." fi Technique 3 (requires another line which MUST be outside all functions): Modified from: How to detect if a script is being sourced # A. Place this line OUTSIDE all functions: (return 0 2>/dev/null) && script_is_being_executed="false" || script_is_being_executed="true" # B. Place these lines anywhere if [ "$script_is_being_executed" == "true" ]; then echo " This script is being EXECUTED." run="true" else echo " This script is being SOURCED." fi Technique 4 [Limitation: does not handle nested scripts!] (MUST be inside a function): Modified from: How to detect if a script is being sourced and Unix & Linux: How to define a shell script to be sourced not run. if [ "${FUNCNAME[-1]}" == "main" ]; then echo " This script is being EXECUTED." run="true" elif [ "${FUNCNAME[-1]}" == "source" ]; then echo " This script is being SOURCED." else echo " ERROR: THIS TECHNIQUE IS BROKEN" fi This is where I first learned about the ${FUNCNAME[-1]} trick: @mr.spuratic: How to detect if a script is being sourced - he learned it from Dennis Williamson apparently.
参见:
[我的回答]bash相当于Python的if __name__ == '__main__'? [我的回答]Unix和Linux:如何定义一个shell脚本来获取而不是运行
其他回答
这似乎在Bash和Korn之间是可移植的:
[[ $_ != $0 ]] && echo "Script is being sourced" || echo "Script is a subshell"
与此类似的行或赋值语句如pathname="$_"(带有稍后的测试和操作)必须位于脚本的第一行或shebang之后的行(如果使用了shebang,则应该用于ksh,以便它在大多数情况下工作)。
我需要一个在[mac, linux]上使用bash的一行程序。版本>= 3,这些答案都不符合要求。
[[ ${BASH_SOURCE[0]} = $0 ]] && main "$@"
@mklement0答案的一个小补充。这是我在脚本中使用的自定义函数,用于确定它是否被引用:
replace_shell(){
if [ -n "$ZSH_EVAL_CONTEXT" ]; then
case $ZSH_EVAL_CONTEXT in *:file*) echo "Zsh is sourced";; esac
else
case ${0##*/} in sh|dash|bash) echo "Bash is sourced";; esac
fi
}
在函数中,zsh的“$ZSH_EVAL_CONTEXT”的输出是toplevel:file:shfunc,而不仅仅是toplevel:file;因此,*:file*应该解决这个问题。
检测Bash脚本是否正在执行或导入的最漂亮方法
我真的认为这是最美丽的方式:
从我的eRCaGuy_hello_world repo中的if__name__==__main__ check_if_sourced_or_executed_best.sh文件:
#!/usr/bin/env bash
main() {
echo "Running main."
# Add your main function code here
}
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
# This script is being run.
__name__="__main__"
else
# This script is being sourced.
__name__="__source__"
fi
# Only run `main` if this script is being **run**, NOT sourced (imported)
if [ "$__name__" = "__main__" ]; then
echo "This script is being run."
main
else
echo "This script is being sourced."
fi
引用:
关于上述技术的其他详细信息,请参见我在这里的另一个回答,包括显示运行输出:bash与Python的if __name__ == '__main__'等价于什么? 这个答案,我第一次了解到“${BASH_SOURCE[0]}”=“$0”
如果您愿意,还可以探索以下替代方案,但我更喜欢使用上面的代码块。
重要提示:使用“${FUNCNAME[-1]}”技术不能正确处理嵌套脚本,即一个脚本调用或来源另一个脚本,而if ["${BASH_SOURCE[0]}" = "$0"]技术可以。这是使用if ["${BASH_SOURCE[0]}" = "$0"]的另一个重要原因。
4种方法确定bash脚本是源脚本还是执行脚本
我已经阅读了关于这个问题和其他一些问题的一堆答案,并提出了4种我想要总结并放在一个地方的方法。
if __name__ == "__main__":
参见:如果__name__ == "__main__":会做什么?在Python中所做的事情。
You can see a full demonstration of all 4 techniques below in my check_if_sourced_or_executed.sh script in my eRCaGuy_hello_world repo. You can see one of the techniques in-use in my advanced bash program with help menu, argument parsing, main function, automatic execute vs source detection (akin to if __name__ == "__main__": in Python), etc, see my demo/template program in this list here. It is currently called argument_parsing__3_advanced__gen_prog_template.sh, but if that name changes in the future I'll update it in the list at the link just above
不管怎样,这里有4个Bash技术:
Technique 1 (can be placed anywhere; handles nested scripts): See: https://unix.stackexchange.com/questions/424492/how-to-define-a-shell-script-to-be-sourced-not-run/424495#424495 if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then echo " This script is being EXECUTED." run="true" else echo " This script is being SOURCED." fi Technique 2 [My favorite technique] (can be placed anywhere; handles nestes scripts): See this type of technique in-use in my most-advanced bash demo script yet, here: argument_parsing__3_advanced__gen_prog_template.sh, near the bottom. Modified from: What is the bash equivalent to Python's `if __name__ == '__main__'`? if [ "${BASH_SOURCE[0]}" == "$0" ]; then echo " This script is being EXECUTED." run="true" else echo " This script is being SOURCED." fi Technique 3 (requires another line which MUST be outside all functions): Modified from: How to detect if a script is being sourced # A. Place this line OUTSIDE all functions: (return 0 2>/dev/null) && script_is_being_executed="false" || script_is_being_executed="true" # B. Place these lines anywhere if [ "$script_is_being_executed" == "true" ]; then echo " This script is being EXECUTED." run="true" else echo " This script is being SOURCED." fi Technique 4 [Limitation: does not handle nested scripts!] (MUST be inside a function): Modified from: How to detect if a script is being sourced and Unix & Linux: How to define a shell script to be sourced not run. if [ "${FUNCNAME[-1]}" == "main" ]; then echo " This script is being EXECUTED." run="true" elif [ "${FUNCNAME[-1]}" == "source" ]; then echo " This script is being SOURCED." else echo " ERROR: THIS TECHNIQUE IS BROKEN" fi This is where I first learned about the ${FUNCNAME[-1]} trick: @mr.spuratic: How to detect if a script is being sourced - he learned it from Dennis Williamson apparently.
参见:
[我的回答]bash相当于Python的if __name__ == '__main__'? [我的回答]Unix和Linux:如何定义一个shell脚本来获取而不是运行
这在后面的脚本中起作用,不依赖于_变量:
## Check to make sure it is not sourced:
Prog=myscript.sh
if [ $(basename $0) = $Prog ]; then
exit 1 # not sourced
fi
or
[ $(basename $0) = $Prog ] && exit