Python - 如何并行远程执行进程并检索其输出

时间:2016-09-09 20:40:13

标签: python ssh subprocess popen

我试图在Python脚本中远程执行未知数量的主机(可能是从一个主机到数百个)的任何命令。这样做的简单方法如下,但很明显,对于许多主机来说,它可能会非常耗时:

listOfOutputs = []
for host in listOfHosts:
  output = subprocess.Popen(shlex.split("ssh %s '<command>'" % host), stdout = subprocess.PIPE).communicate()[0]
  listOfOutputs.append(output)

有没有办法做同样的事情,但让命令并行远程执行所以它不会花费那么长时间?

1 个答案:

答案 0 :(得分:0)

您必须在一个单独的线程中运行Popen.subprocess个调用,这样您就可以在不阻止主程序的情况下启动任意数量的调用。

我做了一个小例子,创建了与主机一样多的线程。没什么大不了,因为线程主要会等待主机回复(否则,线程池本来会更好)

在我的示例中,我有3个主机,并且每个主机都执行ping。输出存储在一个线程安全的输出列表中,最后打印出来:

import threading
import subprocess

listOfOutputs=[]

lock = threading.Lock()

def run_command(args):
    p = subprocess.Popen(["ping","-n","1",args],stdout = subprocess.PIPE)
    output,err = p.communicate()
    lock.acquire()  # listOfOutputs is thread-safe now
    listOfOutputs.append(args+": "+output)
    lock.release()

threads=[]
listOfHosts = ['host1','host2','host3']
for host in listOfHosts:
    t = threading.Thread(target=run_command,args=[host])
    t.start()          # start in background
    threads.append(t)  # store thread object for future join operation


[t.join() for t in threads] # wait for all threads to finish

# print results
for o in listOfOutputs:
    print(o)
    print("-"*50)