我正在使用speedtest-cli在python脚本中获取我的网速。我想通过subprocess.Popen
在shell中运行此命令。
这是终端中的命令:
`speedtest-cli --share > output.log`
speedtest-cli
运行测试,而--share
在输出中为我提供了一个额外的链接,指向最快结果的图像。以下是output.log
:
检索speedtest.net配置... 从M-net测试(xxx.xxx.xxx.xxx)...... 检索speedtest.net服务器列表... 根据ping选择最佳服务器... 主持者XXXXXXXXXXXXXXXXXXXXXX [16.12 km]:20.902 ms 测试下载速度............................................... ................................. 下载:48.32 Mbit / s 测试上传速度............................................... .................................................. ..... 上传:12.49 Mbit / s 分享结果:http://www.speedtest.net/result/670483456.png
如果我在终端中运行命令,我会按预期获得所有测试结果以及目标文件中的链接。我使用此grep trick确认全部为stdout
而非其他渠道:command | grep .
我试图在Python中运行它,如下所示:
subprocess.Popen(['speedtest-cli', '--share', '>', 'output.log`],
stdout=subprocess.PIPE, shell=True)
...我也尝试通过python直接将输出放入文件中:
with open('output.log', 'w') as f:
Popen(['speedtest-cli', '--json', '--share'], stdout=f, shell=True)
这些都不奏效。我用后一种方法创建了一个很好的文件,但链接不包括在内! (上面输出的最后一行)。
使用subprocess
模块反对所有弃用警告和更好的安全性,我变得绝望并尝试os.system()
:
os.system('speedtest-cli --share > output.log')
令人讨厌的是,这有效......在文件中捕获了完整的输出以及链接。
这里发生了什么?如何使用Popen
我使用的是Python 3.5
答案 0 :(得分:2)
使用shell=True
时,Popen
的参数需要是字符串,而不是列表:
subprocess.Popen('speedtest-cli --json --share > output.log',
stdout=subprocess.PIPE, shell=True)
比较
>>> subprocess.Popen('echo hello', shell=True)
>>> hello
和
>>> subprocess.Popen(['echo', 'hello'], shell=True)
>>>
当您传递列表并且使用shell=True
时,只有第一项是相关的,其余部分将被忽略。
如果您想自己收集输出,请考虑subprocess.check_output
:
>>> output = subprocess.check_output(['echo', 'hello'])
>>> output
b'hello\n'
或者:
>>> output = subprocess.check_output('echo hello', shell=True)
check_output
方法适用于Python 2和Python 3.在Python 3中,您还可以使用run方法。