子进程 PIPE stdout 到两个不同的进程
Subprocess PIPE stdout to two different processes
我正在尝试将 subprocess
stdout
重定向到两个不同的进程。
对一个工作正常,但不完全适用于两个不同的进程
代码:
def terminate_processes(*args):
try:
for i in reversed(args):
try:
i.terminate()
except:
pass
except:
pass
def main(x='192.168.0.2'):
# system('sudo nmap -O '+x+'|grep "Running: " > os_detect.txt')
# system('cat os_detect.txt|cut -d " " -f2 > os.txt')
# system('cat os_detect.txt|cut -d " " -f3 > os_version.txt')
p1 = subprocess.Popen(['sudo', 'nmap', '-O', str(x)], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'Running: '], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['cut', '-d', ' ', '-f2'], stdin=p2.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
p4 = subprocess.Popen(['cut', '-d', ' ', '-f3'], stdin=p2.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
while p3.poll() is None:
for line in p3.stdout.readlines():
if line.strip():
print(line.strip())
while p4.poll() is None:
for line in p4.stdout.readlines():
if line.strip():
print(line.strip())
terminate_processes(p1,p2,p3,p4)
正如我所说,理论上应该有效,因为仅使用 p3
而不是 p4
时有效,
但在这种情况下不起作用可能是因为 stdout
被锁定了。
任何指导将不胜感激。
我正在反转终止函数中的 args
数组,导致在杀死父进程之前先杀死子进程。
.read()
通常的工作方式,在我所知道的大多数情况下,为了再次使用它,您必须使用 .seek()
倒回阅读回到原来的地方。
见:
- Why can't I call read() twice on an open file?
你可以做的是使用 communicate
并手动传入标准输出数据(读取一次,传入两次):
out, err = p2.communicate() # out is None, since you don't
p2_output = ''.join(list(out))
p3 = Popen([...], stdin=PIPE, ...)
p4 = Popen([...], stdin=PIPE, ...)
stdout_data3, err = p3.communicate(input=p2_output)
stdout_data4, err = p4.communicate(input=p2_output)
另请注意,与您目前的方式相比,这可能会改变需要进行轮询的方式。
相关:
- How do I write to a Python subprocess' stdin?
- How to read output from subprocess Popen correctly?
我正在尝试将 subprocess
stdout
重定向到两个不同的进程。
对一个工作正常,但不完全适用于两个不同的进程
代码:
def terminate_processes(*args):
try:
for i in reversed(args):
try:
i.terminate()
except:
pass
except:
pass
def main(x='192.168.0.2'):
# system('sudo nmap -O '+x+'|grep "Running: " > os_detect.txt')
# system('cat os_detect.txt|cut -d " " -f2 > os.txt')
# system('cat os_detect.txt|cut -d " " -f3 > os_version.txt')
p1 = subprocess.Popen(['sudo', 'nmap', '-O', str(x)], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'Running: '], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['cut', '-d', ' ', '-f2'], stdin=p2.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
p4 = subprocess.Popen(['cut', '-d', ' ', '-f3'], stdin=p2.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
while p3.poll() is None:
for line in p3.stdout.readlines():
if line.strip():
print(line.strip())
while p4.poll() is None:
for line in p4.stdout.readlines():
if line.strip():
print(line.strip())
terminate_processes(p1,p2,p3,p4)
正如我所说,理论上应该有效,因为仅使用 p3
而不是 p4
时有效,
但在这种情况下不起作用可能是因为 stdout
被锁定了。
任何指导将不胜感激。
我正在反转终止函数中的 args
数组,导致在杀死父进程之前先杀死子进程。
.read()
通常的工作方式,在我所知道的大多数情况下,为了再次使用它,您必须使用 .seek()
倒回阅读回到原来的地方。
见:
- Why can't I call read() twice on an open file?
你可以做的是使用 communicate
并手动传入标准输出数据(读取一次,传入两次):
out, err = p2.communicate() # out is None, since you don't
p2_output = ''.join(list(out))
p3 = Popen([...], stdin=PIPE, ...)
p4 = Popen([...], stdin=PIPE, ...)
stdout_data3, err = p3.communicate(input=p2_output)
stdout_data4, err = p4.communicate(input=p2_output)
另请注意,与您目前的方式相比,这可能会改变需要进行轮询的方式。
相关:
- How do I write to a Python subprocess' stdin?
- How to read output from subprocess Popen correctly?