【问题标题】:Ignore failure on Source command in Bash script在 Bash 脚本中忽略 Source 命令失败
【发布时间】:2020-05-02 13:36:57
【问题描述】:

所以我知道有很多关于堆栈溢出的答案可以忽略 bash 脚本中的错误。不过,它们似乎都不适用于 source 命令。

我已经尝试过久经考验的真实source ../bin/activate || true

我尝试在运行命令之前设置set -e

我试过source ../bin/activate 2>&1 /dev/null

我尝试在运行命令之前设置set +e。这也不起作用。

但在每次运行此代码时,我都会收到

run.01:第 12 行:../bin/activate:没有这样的文件或目录

这个问题的背景是我正在创建一个运行一些 python 代码的简单 bash 脚本。指导用户如何创建特定的虚拟环境,如果设置正确,此行将自动激活它,否则,这应该忽略激活失败并在当前激活的任何环境中继续运行命令。

# Try virtual environment

source ../bin/activate || true

## Run.

code="../src-01/driver.v01.py"

## --------------------
graphInputFile="undirected_graph_01.inp"
graphType="undirected"
srcColId="0"
desColId="1"
degreeFind="2"
outFile="count.undirected.num.nodes.out"

python $code  -inpGraphFile $graphInputFile  -graphFormat $graphType  -colSrcId $srcColId -colDesId $desColId  -degreeFind $degreeFind  -output_file $outFile

无论source ../bin/activate 命令是否成功,python 命令都应该执行。我有点不知所措,为什么这些解决方案都不起作用,并且目前假设source 在特定情况下可能会执行与正常命令不同的操作。

编辑:

我按要求将 shebang #!/bin/bash -x 添加到我的文件中,但这没有做任何事情。

这是我运行此脚本时的确切终端输出。

Lucas-Macbook:test-01 lucasmachi$ sh run.01
run.01: line 14: ../bin/activate: No such file or directory
Lucas-Macbook:test-01 lucasmachi$ 

run.01 是 bash 脚本的名称。

另外澄清一下,我展示的代码没有经过审查。这就是整个脚本(除了现在提到的 shebang 在顶部。)

【问题讨论】:

  • 您要解决什么实际问题?该脚本将显示一条错误消息并在没有|| true 的情况下继续运行,除非您在set -e 下运行。
  • 这是大量未引用变量的集合。它在这里可能是无害的,但有一种非常难闻的气味。阅读When to wrap quotes around a shell variable?
  • 不要使用sh run.01,现在你已经设置了shebang使用./run.01。如果出现权限错误,请使用chmod +x ./run.01 使run.01 可执行,然后再次使用./run.01sh 是一个指向您的默认 shell 的链接,但如果它是 bash(我也假设其他人),它会在称为 sh 时以符合 POSIX 的模式运行您的脚本,除非您这样做,否则对您没有帮助正在尝试使您的脚本可移植,并且可能会解释您的一些麻烦
  • @Vapidant 您的编辑刚刚显示您正在使用sh 而不是bash 运行脚本 - 这可能是这种行为的原因。就个人而言,我在使用sh 而不是bash 时看到了类似的奇怪现象,并且浪费了相当多的时间来调试它,然后当我意识到错误是什么时,我的头撞在了键盘上。尝试以bash run01.sh 运行它,或者按照此处的建议将shebang 作为脚本的第一行(如果您不想看到调试输出,可以省略-x),执行chmod +x run01.sh 然后运行它正如./run01.sh(正如@Aaron 已经建议的那样)
  • 也许还可以查看stackoverflow.com/a/42666651/874188,其中有一个关于此常见问题解答的部分。

标签: python bash macos shell terminal


【解决方案1】:

您可以在代码中添加验证以在获取文件之前检查文件是否存在:

[[ -f "../bin/activate" ]] && source ../bin/activate

如果路径文件存在,则在路径前使用 -f 标志将返回 true,否则返回 false。

bash if 语句的单行语法如下:

[[ Condition that returns true or false ]] && Exec if true 

【讨论】:

    【解决方案2】:

    这是 4.0 之前的 Bash 版本中的一个错误(macOS 卡在 3.2 上)。

    鉴于此脚本:

    #!/bin/bash
    set -e
    echo "Running $BASH_VERSION"
    source "does not exist" || true
    echo "Continuing"
    

    在 macOS 上运行会说:

    macos$ ./myscript
    Running 3.2.57(1)-release
    ./myscript: line 3: does not exist: No such file or directory
    

    在具有更新的 bash 版本的现代系统上,您会得到预期的行为:

    debian$ ./myscript
    Running 5.0.11(1)-release
    ./myscript: line 3: does not exist: No such file or directory
    Continuing
    

    如果您需要支持 macOS 和 Bash 3.2,请先运行 set +e 以禁用 errexit,然后可以选择重新启用它。

    【讨论】:

      【解决方案3】:

      我在使用 gitlab 管道时遇到了这个问题。以上都不适合我,但结合答案确实有效:

      [[ -f "${ENVIRONMENT}_test" ]] && source "${ENVIRONMENT}_test" || true
      

      这将我带到我需要去的地方,希望它会在未来对某人有所帮助。

      【讨论】:

        猜你喜欢
        • 2014-04-04
        • 2016-09-20
        • 2019-12-19
        • 2019-05-28
        • 1970-01-01
        • 1970-01-01
        • 2015-05-20
        • 2023-02-11
        • 2013-09-28
        相关资源
        最近更新 更多