我正在尝试将stderr重定向到stdout并读取命令的输出。它看起来像代码工作,但当它到达输出的末尾时,它会抛出异常
代码:
with Popen(["bash", "-c", "for ((i=0;i<10;i++)); do echo $i; sleep .5; done"],
stderr=subprocess.STDOUT) as proc:
out, err = proc.communicate()
for line in out:
if line:
print(line)
输出:
0
1
2
3
4
5
6
7
8
9
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-3c150d6a4092> in <module>()
2 stderr=subprocess.STDOUT) as proc:
3 out, err = proc.communicate()
----> 4 for line in out:
5 if line:
6 print(line)
TypeError: 'NoneType' object is not iterable
答案 0 :(得分:1)
我知道,你可以用另一种方法实现你想要的东西,但我想解释你的第一个版本是多么令人满意。
问题是PIPE
中没有输出任何proc
,因此输出不会导致&#34;旅行&#34;通过你的脚本,它直接进入屏幕,这就是你看到输出的原因:
0
1
2
3
4
5
6
7
8
9
然后在行中:
out, err = proc.communicate() # out is None, since you don't
# pass the argument "stdout=subprocess.PIPE"
# when creating proc.
以及稍后当您尝试迭代out
时:
for line in out: # TypeError: 'NoneType' object is not iterable
... # We are talking about out variable here, which is None.
print(line) # This line never get hit.
这里有一个小例子,将stdout
重定向到stderr
并使用communicate
:
import subprocess
import sys
proc = subprocess.Popen(['ls'], stderr=sys.stdout, shell=True) # Not the use of sys.stdout
out, err = proc.communicate()
print(err.decode("utf-8"))
答案 1 :(得分:0)
哦,看起来我需要设置stdout = PIPE,我不需要communicate()
with Popen(["bash", "-c", "for ((i=0;i<10;i++)); do echo $i; sleep .5; done"],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc:
for line in proc.stdout:
print(line.decode().rstrip())
使用J.F. Sebastian的universal_newlines提示:
with Popen(["bash", "-c", "for ((i=0;i<10;i++)); do echo $i; sleep .5; done"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True) as proc:
for line in proc.stdout:
print(line, end='')
答案 2 :(得分:0)
TypeError:&#39; NoneType&#39;对象不可迭代
您应添加stdout=PIPE
否则.communicate()
始终会为None
返回out
。
btw,如果您的代码使用stdout=PIPE, stderr=STDOUT
,那么err
总是 None
而out
包含合并的stdout / stderr作为单个字节字符串,即,for byte in out
一次产生一个字节,不行。
如果您设置stdout=PIPE, stderr=PIPE
并致电.communicate()
,则可以单独获取stdout / stderr。