【发布时间】:2014-02-04 04:12:19
【问题描述】:
我注意到两种不同的行为,两种方法应该会产生相同的结果。
目标 - 使用 subprocess 模块执行外部程序,发送一些数据并读取结果。
外部程序为PLINK,平台为WindowsXP,Python 3.3版本。
主要思想-
execution=["C:\\Pr..\\...\\plink.exe", "-l", username, "-pw", "***", IP]
a=subprocess.Popen(execution, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=False)
con=a.stdout.readline()
if (con.decode("utf-8").count("FATAL ERROR: Network error: Connection timed out")==0):
a.stdin.write(b"con rout 1\n")
print(a.stdout.readline().decode("utf-8"))
a.stdin.write(b"infodf\n")
print(a.stdout.readline().decode("utf-8"))
else:
print("ERROR")
a.kill()
到目前为止一切顺利。
现在,我希望能够执行一个循环(在每次写入子进程的标准输入之后),等待子进程的标准输出 EOF,打印它,然后是另一个标准输入命令,等等。
所以我首先尝试了之前关于同一主题的讨论(live output from subprocess command、read subprocess stdout line by line、python, subprocess: reading output from subprocess)。
它没有工作(它永远挂起),因为 PLINK 进程一直保持活动状态,直到我自己杀死它,所以等待子进程的标准输出到达 EOF 或在标准输出为时执行循环是没有用的真的,因为在我杀死它之前它永远都是真的。
所以我决定每次写入标准输入时都从标准输出读取两次(对我来说已经足够了)-
execution=["C:\\Pr..\\...\\plink.exe", "-l", username, "-pw", "***", IP]
a=subprocess.Popen(execution, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=False)
con=a.stdout.readline()
if (con.decode("utf-8").count("FATAL ERROR: Network error: Connection timed out")==0):
a.stdin.write(b"con rout 1\n")
print(a.stdout.readline().decode("utf-8"))
print(a.stdout.readline().decode("utf-8")) //the extra line [1]
a.stdin.write(b"infodf\n")
print(a.stdout.readline().decode("utf-8"))
print(a.stdout.readline().decode("utf-8")) //the extra line [2]
else:
print("ERROR")
a.kill()
但据我所知,第一个额外的readline() 永远挂起,原因与我提到的相同。第一个额外的readline() 永远等待输出,因为在第一个readline() 中已经读取了唯一的输出,并且因为PLINK 是活动的,所以该函数只是“坐”在那里并等待获得新的输出行。
所以我尝试了这段代码,期待同样的挂起,因为 PLINK 在我杀死它之前永远不会死-
execution=["C:\\Pr..\\...\\plink.exe", "-l", username, "-pw", "***", IP]
a=subprocess.Popen(execution, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=False)
con=a.stdout.readline()
if (con.decode("utf-8").count("FATAL ERROR: Network error: Connection timed out")==0):
a.stdin.write(b"con rout 1\n")
print(a.stdout.readline().decode("utf-8"))
a.stdin.write(b"infodf\n")
print(a.stdout.readline().decode("utf-8"))
print(a.communicate()[0].decode("utf-8")) //Popen.communicate() function
else:
print("ERROR")
a.kill()
我试过了,因为根据communicate() 的文档,函数会等到进程结束,然后才结束。此外,它从标准输出读取直到 EOF。 (与读写stdout和stdin一样)
但是communicate() 完成并且没有挂起,与前一个代码块相反。
我在这里缺少什么?为什么使用communicate()时PLINK结束,但使用readline()时却没有?
【问题讨论】:
标签: python subprocess python-3.3