subprocess.Popen() 的第一个参数告诉系统要运行什么。
当它是一个列表时,您需要使用shell=False。巧合的是,它在 Windows 中按您希望的那样工作;但在类 Unix 平台上,您只需传入一些通常会被忽略的参数。实际上,
/bin/sh -c 'echo' '$HOME'
这只会导致第二个参数不用于任何内容(我使用单引号来强调这些只是静态字符串)。
以我的拙见,在这种情况下,Python 应该会抛出错误。在 Windows 上也是如此。这是一个应该被捕获并报告的错误。
(在相反的情况下,如果指定了shell=False,但你传入的字符串不是有效命令的名称,你最终还是会得到一个错误,如果你有一个模糊的想法,这是有道理的发生了什么事。)
如果你真的知道你在做什么,你可以让第一个参数访问后面的参数;例如
/bin/sh -c 'printf "%s\n" "$@"' 'ick' 'foo' 'bar' 'baz'
将在单独的行上打印 foo、bar 和 baz。 (“第零个”参数——这里是'ick'——用于填充$0。)但这只是一个模糊的推论;不要试图将它用于任何事情。
另外,如果您只想运行命令,则不应使用subprocess.Popen()。 subprocess.run() 文档更详细地告诉您这一点。使用text=True 你会得到一个字符串而不是字节。
result = subprocess.run('echo "$HOME"', shell=True,
text=True, capture_output=True, check=True)
print(result.stdout, result.stderr)
当然,os.environ['HOME'] 允许您从 Python 中访问 $HOME 的值。这也可以让你avoid shell=True which you usually should if you can.