我知道标题有点奇怪,但我不确定如何更好地用词。
我正在使用$(return &> /dev/null)
来检测文件是否是源文件。
我知道这种方法不是100%可靠的,但是到目前为止,它对我没有问题。我已经想出了解决该问题的方法,但是我不知道为什么会发生这种情况。
编辑:这是用于公司内部的项目,并不旨在与POSIX兼容或可移植到其他外壳。
我已经在三种不同的系统上进行了尝试,并且得到了相同的结果:
Redhat 6.9; $BASH_VERSION=4.1.2(1)-release
Mint 18.2; $BASH_VERSION=4.3.48(1)-release
Arch; $BASE_VERSION=4.4.23(1)-release
如果$?
时$(return &> /dev/null)
为1(假),则返回码相反。
$ hr | cat test_0source - test_0source.sh; hr; ./test_0source
#!/bin/bash
# test_0source
false
test_0source.sh
false
source test_0source.sh
true
test_0source.sh
true
source test_0source.sh
========================================
#!/bin/bash
# test_0source.sh
# shellcheck disable=SC2091
$(return &> /dev/null)
echo "$?"
========================================
1
1
1
0
我希望能见到
1
0
1
0
我的解决方法是在true
检查之前添加return
。虽然这给了我正确的结果,但添加false
而不是true
会使return
的检查始终返回1。
我意识到我在这里缺少一些基本的知识,但是我没有看到。为什么这样做呢?
编辑:我的$值不正确?在上面的最初解释中。
更新:
首先,由于@ ondre-k,使用$(return 0 &> /dev/null)
可解决问题。
Ondre还指出,将BASH_SOURCE与$ 0进行比较是一种更惯用的方法:
$ hr | cat test_0bs - test_0bs.sh; hr; test_0bs | less
#!/bin/bash
# test_0bs
false
test_0bs.sh
hr
false
source test_0bs.sh
hr
true
test_0bs.sh
hr
true
source test_0bs.sh
========================================
#!/bin/bash
# test_0bs.sh
if [[ ${BASH_SOURCE[0]} == "$0" ]]; then
echo "We are not being sourced."
else
echo "We are being sourced."
fi
========================================
We are not being sourced.
========================================
We are being sourced.
========================================
We are not being sourced.
========================================
We are being sourced.
我怀疑这周围可能有一个或两个极端的情况,但在我看来,这些情况将变得无关紧要。
答案 0 :(得分:1)
您正在做的事情基本上是在“滥用”以下事实:返回只能从函数或源脚本中发生,并假设在可能返回(我们已获得源)和{{1}的情况下返回0
如果不是,则在抑制错误输出的同时。您也可以在子shell中执行此操作。奇怪的是,使用1
放置bash还是可以的,但是不会从源脚本中返回并继续运行。到目前为止,上帝。
问题是,“ {裸体”(未指定显式值)return
,就像return
传播最后看到的返回代码(紧接其后的命令的返回代码)。>
换句话说,exit
与false; return
是同一件事。您也可以通过将return 1
替换true
和false
来尝试一下,看看会发生什么。您在测试中寻找到(exit 255)
的{{1}}不是错误,而是测试过程中的“错误:您现在不能说1
”,而只是一个普通的{{1 }}已从其前面的命令(return
)返回了最后一个。如果您放弃了return
重定向,这种区别也将变得显而易见。
TL; DR可以使此构造按预期工作,将其更改为return
。
我希望我不会错过一些极端的情况,但是通过比较执行脚本的名称和源文件,这可以作为bash的替代方法。如果没有源文件,则false
的计算结果为stderr
,如果有文件,则计算结果为return 0
。或将[[ "${BASH_SOURCE}" = ${0} ]]
替换为0
,以获得与上述1
情况相同的值含义。