【问题标题】:Why doesn't Popen.communicate() return the output after the "||" operator?为什么 Popen.communicate() 在 "||" 之后不返回输出操作员?
【发布时间】:2021-09-24 01:48:54
【问题描述】:
import subprocess

cmd = "source ~/.bash_profile || echo hello"
proc = subprocess.Popen(cmd,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        shell=True)
(out, err) = proc.communicate()
code = proc.returncode
print(f"code:{code}, out:{out}, err:{err}")

输出:

code:1, out:b'', err:b'/bin/sh: /Users/xxx/.bash_profile: 没有这样的文件或目录\n'

我没有 bash_profile,但为什么 out 不包含 "hello"

【问题讨论】:

  • 这似乎更像一个 bash 问题而不是 python 问题
  • 这是在 MacOS 上吗?您使用的是 bash 还是 zsh?您的代码在 Linux 上按预期工作。
  • @TimRoberts 我正要说同样的话,代码在 debian 10 上使用 bash 打印 code:0, out:b'hello\n', err:b'/bin/sh: 1: source: not found\n'(如预期的那样)
  • 是的,它在 MacOS 上
  • @jemand771 它与 Python 有关,因为当您在 macOS 终端上直接执行 source ~/.bash_profile_does_not_exist || echo hello 时,您会看到 both 错误 "你好”字符串。但是当你用subprocess把它放到这样的Python脚本中时,“你好”确实不会出现。

标签: python bash macos subprocess


【解决方案1】:

bashsh 之间可能存在差异 您可以在没有 python 的情况下重现它。 python默认依赖/bin/sh也是有道理的,所以它暴露了行为

#!/bin/sh
. abc || echo hello 
 # output: ./test.sh: line 3: .: abc: file not found

#!/bin/bash    
. abc || echo hello
# output: ./test.sh: line 3: abc: No such file or directory
# hello

可能通过executable 参数将默认设置更改为/bin/bash 可以以某种方式纠正它

cmd = "source ~/.bash_profile || echo hello"
proc = subprocess.Popen(cmd,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        shell=True,
                        executable="/bin/bash")

【讨论】:

  • 但是为什么呢?我需要源来获取环境路径?
  • 我怀疑这仅仅是因为#!/bin/sh 导致bash 在posix 模式下运行。 #!/bin/bash --posix 你会得到类似的行为
  • @WilliamPursell 这是真的
【解决方案2】:

bash 手册页中似乎没有记录此行为,但开放标准指出:If no readable file is found, a non-interactive shell shall abort; an interactive shell shall write a diagnostic message to standard error, but this condition shall not be considered a syntax error. (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_18_01) 当从 python 以非交互方式运行时,shell 只是中止而不运行||之后的代码

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 2023-03-14
    • 2021-12-23
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多