首页 > 解决方案 > 双管道运算符和 python virtualenv 的奇怪行为

问题描述

我有一个运行源代码的 bash 构建脚本,因此我可以激活 Python 虚拟环境。我首先使用python3.7 -m unittest. 但是,如果这些失败,我不想运行主程序。所以,我需要停用虚拟环境(使终端恢复到原来的状态),然后return 1退出构建脚本。

所以我的脚本看起来像这样

# activate virtual env ...

python3.7 -m unittest || deactivate; return 1;
python3.7 app.py

deactivate

当单元测试失败时,python3.7 -m unittest返回1并且虚拟环境按预期停用。

当单元测试成功运行时,python3.7 -m unittest返回0,但奇怪的是管道的右侧似乎有点运行。我还没有弄清楚这是否是 bash 或 with 的奇怪之处,deactivate但这里有一些行为示例:

(exit 0) || deactivate; echo "Tests failed"; return 1; (Output: "Tests failed", deactivate not run)

(exit 0) || echo "Deactivating"; deactivate; echo "Tests failed"; return 1; (Output: "Tests failed", deactivate ran)

(exit 0) || echo "Tests failed"; return 1; (Output: Nothing, deactivate not run)

这三个中的最后一个案例是有道理的并且遵循预期的行为,其他两个则没有。

标签: pythonbash

解决方案


这与Bash Pitfall 22有关,但不完全相同。重要的一点是如何对语句进行分组:

cmd1 || cmd2; cmd3

将运行cmd1,如果退出状态为非零,cmd2; 那么,无论如何cmd3

意图是这样的:

cmd1 || { cmd2; cmd3; }

如果cmd1失败,运行cmd2cmd3.


推荐阅读