Python subprocess.Popen:使用shell = True运行多个命令,但它似乎并不等待所有命令完成

问题描述

我正在尝试使用subprocess.Popen对Kafka使用者组进行检查并记录其状态,但是它似乎没有在等待所有命令的运行。它没有给我任何标准输出,但它还返回了退出代码0。

prompt = ["cd","~/path/to/kafka_2.11-2.1.0;","pwd;","./bin/kafka-consumer-groups.sh","--bootstrap-server","localhost:9092","--describe","--group","groupname"]

response = subprocess.run(prompt,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,check=True)
print(response)

打印:

CompletedProcess(args=['cd','~/path/to/kafka_2.11-2.1.0;','pwd;','./bin/kafka-consumer-groups.sh','--bootstrap-server','localhost:9092','--describe','--group','groupname'],returncode=0,stdout=b'',stderr=b'')

pwd命令主要用于测试它是否会返回任何粗壮,不会被保留。

我已经查看了子流程的文档,但没有发现任何暗示它无法捕获多个stdout的信息。另外,根据日志,在我的计算机上运行cd ~path/to/kafka_2.11-2.1.0; pwd; ./bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group groupname时大约需要10-15秒,而CompletedProcess会在不到10毫秒的时间内返回。

请注意,我正在使用python3.5.2

解决方法

我发现了我的错误。 cd不适用于子进程,但是子进程提供了cwd命名参数,该参数接受运行参数所需的路径。之所以这么快返回CompletedProcess是因为它成功更改了目录然后退出了子进程。

对不起,直到遇到this question,我也没有想到cd是罪魁祸首。

,

您的错误比您想像的更为根本。您的代码运行

sh -c 'cd'

,其中$0设置为目录,$1设置为pwd;,依此类推;所以非常离您想要的东西很远。 (只需cd即可切换到您的主目录;然后,shell退出,不对您传入的所有参数进行任何处理,Python继续返回启动子进程之前的当前目录。)

通常,使用shell=True传递一个字符串作为第一个参数,如果没有外壳,则传递一个字符串列表。

subprocess.run(r"cd foo; pwd; use shell commands to your heart\'s content; run as many processes as you like as subprocesses of your shell subprocess",shell=True)
subprocess.run(['/bin/echo','one','single','process','with','arguments])