import subprocess as sp res = sp.check_output("bashscript", shell=True)
bashscript包含以下行:
ssh -MNf somehost
这将打开与某个远程主机的共享主连接,以允许一些后续操作.
执行python脚本时,它会提示输入ssh行的密码,但是在输入密码后它会阻塞,并且永远不会返回.当我按ctrl-C终止脚本时,我看到连接已正确建立(因此ssh行已成功执行).
使用check_call而不是check_output时,我没有此阻塞问题,但check_call不检索stdout.我想了解究竟是什么导致了check_output的阻塞行为,可能与ssh -MNf的一些微妙之处有关.
只要/ bin / sh进程退出而不等待后代进程,check_call()就会返回.check_output()等待直到读取所有输出.如果ssh继承了管道,那么check_output()将一直等到它退出(直到它关闭其继承的管道结束).
check_call()代码示例:
#!/usr/bin/env python import subprocess import sys import time start = time.time() cmd = sys.executable + " -c 'import time; time.sleep(2)' &" subprocess.check_call(cmd, shell=True) assert (time.time() - start) < 1
输出未读取; check_call()立即返回,无需等待孙子后台python进程.
check_call()只是Popen().wait(). Popen()启动外部进程并立即返回,而不等待它退出. .wait()收集进程的退出状态 – 它不等待其他(孙子)进程.
如果读取输出(它被重定向和孙子python
进程继承stdout管道):
start = time.time() subprocess.check_output(cmd, shell=True) assert (time.time() - start) > 2
然后它等待,直到继承管道的后台python进程退出.
check_output()调用Popen().communic()来获取输出. .communicate()在内部调用.wait(),即check_output()也等待shell退出,check_output()等待EOF.
如果孙子没有继承管道,那么check_output()不会等待它:
start = time.time() cmd = sys.executable + " -c 'import time; time.sleep(2)' >/dev/null &" subprocess.check_output(cmd, shell=True) assert (time.time() - start) < 1
孙子的输出被重定向到/ dev / null,即它不继承父管道,因此check_output()可以在不等待的情况下退出.
注意:&最后,将孙子python进程放入后台.它不适用于Windows默认情况下shell = True启动cmd.exe的Windows.