Kev*_* S. 17 python ssh bash subprocess
我的python脚本(python 3.4.3)通过子进程调用bash脚本:
import subprocess as sp
res = sp.check_output("bashscript", shell=True)
Run Code Online (Sandbox Code Playgroud)
该bashscript包含以下行:
ssh -MNf somehost
Run Code Online (Sandbox Code Playgroud)
这将打开与某个远程主机的共享主连接,以允许一些后续操作.
执行python脚本时,它将提示该ssh行的密码,但在输入密码后它会阻塞,并且永远不会返回.当我按ctrl-C终止脚本时,我看到连接已正确建立(因此ssh行已成功执行).
使用时,我没有这个阻塞问题check_call,而不是check_output,但check_call不检索标准输出.我想了解究竟是什么导致阻塞行为check_output,可能与某些微妙的相关ssh -MNf.
jfs*_*jfs 42
check_call()只要/bin/sh进程退出而不等待后代进程,就会返回.
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
Run Code Online (Sandbox Code Playgroud)
输出未读取; 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
Run Code Online (Sandbox Code Playgroud)
然后它等待,直到继承管道的后台python进程退出.
check_output()调用Popen().communicate(),获取输出.内部.communicate()调用.wait()ie,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
Run Code Online (Sandbox Code Playgroud)
孙子的输出被重定向到/dev/nullie,它不会继承父管道,因此check_output()可以在不等待它的情况下退出.
注意:&最后将孙子python进程放入后台.它在默认shell=True启动cmd.exe的Windows上不起作用.
| 归档时间: |
|
| 查看次数: |
24786 次 |
| 最近记录: |