代码之家  ›  专栏  ›  技术社区  ›  harleypig

在命令返回1后,使用RETURN检查当前文件的来源是否会产生反向结果

  •  1
  • harleypig  · 技术社区  · 7 年前

    我知道书名有点奇怪,但我不知道该怎么说才好。

    我在用 $(return &> /dev/null) 检测文件是否来源。

    我知道这种方法不是百分之百可靠的,但它以前对我没有问题。我已经知道如何解决这个问题,但我不明白为什么会发生这种情况。

    编辑:这是一个内部公司项目,不打算是POSIX兼容或可移植到其他shell。

    我在三个不同的系统上尝试过,结果都是一样的:

    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
    

    如果 $? 是1(错误),当 $(返回&>/dev/null) 返回代码被颠倒。

    $ 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 而不是 造成 返回 选中可始终返回1。

    我意识到我这里缺少一些基本的东西,但我看不到。为什么要这样做?

    编辑:我的美元值不正确?在我上面的初步解释中。

    更新: 首先,使用 $(return 0 &> /dev/null) 多亏了@ondre-k,解决了这个问题。

    Ondre还指出,将bash_源代码与$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.
    

    我怀疑这附近可能有一两个边缘案件,但在我看来,这些案件将不那么令人担心。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Ondrej K.    7 年前

    您所做的基本上是“滥用”这样一个事实,即返回只能从函数或源脚本发生,并且假定它产生 0 当有可能退货时(我们是采购商),以及 1 如果不是,则在抑制错误输出时。你也可以在一个小地狱里这样做。奇怪的是,bash在 return 但不会从源脚本返回并继续运行。到目前为止,上帝。

    问题是,“裸”(未指定显式值) 返回 ,就像 exit 传播上一次看到的返回代码(紧接其前面的命令的返回代码)。

    换言之 false; return 会和 return 1 . 您也可以通过更换 true false 通过 (exit 255) 看看会发生什么。这个 你要找的是 返回 跟随错误不是“错误:你不能说 返回 现在“正如你的测试所寻找的,但只是一个普通的 返回 从它前面的命令返回最后一个( )如果你放弃了 stderr 重定向。

    tl;dr若要使此构造按预期工作,请将其更改为 return 0 .


    我希望我没有遗漏一些角落的情况,但是这应该可以作为与bash的替代方法,通过比较执行脚本和源文件的名称。 [[ "${BASH_SOURCE}" = ${0} ]] 评估为 如果文件没有来源,并且 如果有的话。或替换 = 具有 != 获得与 返回 以上情况。

    推荐文章