bash与Python';s`if_uuuname_uuu=='__主要的&';`?
在Bash中,我希望能够同时生成脚本和执行文件。如果Bash的bash与Python';s`if_uuuname_uuu=='__主要的&';`?,bash,Bash,在Bash中,我希望能够同时生成脚本和执行文件。如果Bash的与Python的等价,那么它的值是多少? 关于Stackoverflow,我没有找到一个现成的问题/解决方案(我怀疑我的提问方式与现有的问题/答案不匹配,但由于我的Python经验,这是我能想到的最明显的表达问题的方式) p、 (如果我有更多的时间,我会写一个简短的回复): 问题是“如何检测脚本是否正在源代码中”,但问题是“如何创建既可以源代码又可以作为脚本运行的bash脚本?”。此问题的答案可能使用上一个问题的某些方面,但有以下附
与Python的等价,那么它的值是多少?
关于Stackoverflow,我没有找到一个现成的问题/解决方案(我怀疑我的提问方式与现有的问题/答案不匹配,但由于我的Python经验,这是我能想到的最明显的表达问题的方式)
p、 (如果我有更多的时间,我会写一个简短的回复): 问题是“如何检测脚本是否正在源代码中”,但问题是“如何创建既可以源代码又可以作为脚本运行的bash脚本?”。此问题的答案可能使用上一个问题的某些方面,但有以下附加要求/问题:
- 一旦检测到脚本正在被源化,什么是不运行脚本的最佳方式(并避免意外(除了导入感兴趣的函数外),如添加/删除/修改环境/变量)
- 一旦您检测到脚本正在运行而不是源代码,那么实现脚本的规范方式是什么(将脚本放在函数中?或者可能只是放在if语句之后?如果将脚本放在if语句之后,它会有副作用吗
- 我在Bash上找到的大多数google搜索都没有涵盖这个主题(一个既可以源代码又可以执行的Bash脚本),实现这个主题的标准方法是什么?没有涵盖这个主题是因为它不被鼓励还是不好做?有没有问题
- 没有。我通常使用以下方法:
#!/bin/bash
main()
{
# validate parameters
echo "In main: $@"
# your code here
}
main "$@"
如果你想知道这个脚本是否是source
'd,只需将你的main
调用打包即可
if [[ "$_" != "$0" ]]; then
echo "Script is being sourced, not calling main()"
else
echo "Script is a subshell, calling main()"
main "$@"
fi
参考:解决方案:
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
我添加这个答案是因为我想要一个以模仿Python的的样式编写的答案,如果uuu name uuuuuu=='uuuuu main uuu'
但是在Bash中
关于BASH\u SOURCE
vs$\u
的用法,我使用BASH\u SOURCE
,因为它似乎比$\u
更健壮(,)
下面是一个我用两个Bash脚本测试/验证的示例 带有
xyz()
函数的script1.sh:
#!/bin/bash
xyz() {
echo "Entering script1's xyz()"
}
main() {
xyz
echo "Entering script1's main()"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
试图调用函数xyz()
的script2.sh:
我在所有脚本的底部都使用了以下构造:
[[ "$(caller)" != "0 "* ]] || main "$@"
脚本中的所有其他内容都在函数中定义或是全局变量
调用者
被记录为“返回当前子例程调用的上下文”。当脚本来源时,调用者的结果以来源于此脚本的脚本行号开始。如果未来源于此脚本,则以“0”开始。
我使用!=
和|
而不是=
和&
的原因是后者将导致脚本在来源时返回false。如果外部脚本在集-e
下运行,则可能会导致外部脚本退出
请注意,我只知道这适用于bash。它不适用于posix shell。我不知道其他shell,如ksh或zsh。使用FUNCNAME
方法1:测试FUNCNAME[0]
(Bash 4.3+)
运行示例:
$ bash funcname_test.sh
hello
$ source funcname_test.sh
$ _main
hello
$ bash return_test.sh
hello
$ source return_test.sh
$ _main
hello
我不确定我是如何偶然发现这个功能的。虽然没有很好地描述它的功能,但下面是它的实际功能:
- 执行的脚本:
是${FUNCNAME[0]}
main
- 源代码脚本:
是${FUNCNAME[0]}
源代码
- Shell函数:
是函数的名称${FUNCNAME[0]}
FUNCNAME[1]
(Bash 4.2)
在Bash 4.2中,FUNCNAME
仅在函数中可用,其中FUNCNAME[0]
是函数的名称,FUNCNAME[1]
是调用方的名称。因此对于顶级函数,FUNCNAME[1]
将在执行的脚本中成为main
,或者在源代码脚本中成为source
这个例子应该像上面的例子一样工作
#!/bin/bash
get_funcname_1(){
printf '%s\n' "${FUNCNAME[1]}"
}
_main(){
echo hello
}
if [[ $(get_funcname_1) == main ]]; then
_main
fi
返回2>/dev/null
对于一种惯用的Bash方法,您可以使用return
如下所示:
_main(){
echo hello
}
# End sourced section
return 2> /dev/null
_main
运行示例:
$ bash funcname_test.sh
hello
$ source funcname_test.sh
$ _main
hello
$ bash return_test.sh
hello
$ source return_test.sh
$ _main
hello
如果脚本是源代码,return
将返回到父脚本(当然),但是如果脚本被执行,return
将产生一个隐藏的错误,脚本将继续执行
我已经在GNUBash4.2到4.4上测试过了
这是基于上的一部分
警告:这在大多数其他shell中不起作用。由于Python不太流利,我不理解您的问题。:)您希望能够检测脚本是否显式运行,或者通过使用
source
或点运算符包含在另一个脚本中?@ghoti例如,我有一个脚本script1.sh
,带有一个函数xyz()
,我想在另一个脚本script2.sh
中使用。当我从script2中获取script1时,script1会以某种方式退出,从而阻止我在script2中调用xyz()
。(对我提到的python位提供了一个很好的解释)由于$0
本身可能存在重复,因此我也不确定这是否一定会起作用。@EtanReisner如果您认为有更好的解决方案,请随意编写您自己的答案。(此时有60多票赞成使用$0
来解决两个不同的问题(我没有)。我只想指出$0
是不可靠的,这可能会在这里造成问题(但在大多数情况下可能不应该)。${BASH_SOURCE[0]
比${0}更好地发挥作用
是否: