使用Paramiko同时创建多个SSH连接
下面的代码通过SSH在一台机器上运行grep命令,并打印出结果:
import sys, os, string
import paramiko
cmd = "grep -h 'king' /opt/data/horror_20100810*"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.10.3.10', username='xy', password='xy')
stdin, stdout, stderr = ssh.exec_command(cmd)
stdin.write('xy\n')
stdin.flush()
print stdout.readlines()
我该如何同时在五台机器上运行grep(这样就不会有很大的延迟),然后把所有结果放在五个变量里,最后把它们全部打印出来呢?
3 个回答
在编程中,有时候我们需要处理一些数据,这些数据可能来自不同的地方,比如用户输入、文件或者网络请求。为了让程序能够理解这些数据,我们通常会把它们转换成一种统一的格式。这样做的好处是,程序在处理这些数据时会更加简单和高效。
例如,假设我们有一个用户输入的字符串,我们可能需要把它转换成一个数字,这样才能进行数学运算。这个过程叫做“数据转换”。在编程中,常见的转换方式包括把字符串变成整数、把整数变成浮点数等。
另外,处理数据时还要注意数据的类型。不同类型的数据在程序中有不同的表现,比如整数、浮点数、字符串等。了解这些类型可以帮助我们更好地管理和使用数据。
总之,数据转换和理解数据类型是编程中非常重要的基础知识,掌握这些可以让我们写出更好的程序。
#! /usr/bin/env python3
import sys, os, string, threading
try:
import paramiko
#import paramiko package
except:
im = input("Paramiko module is missing. Do you want to install[Y/N]:")
im = im.upper()
if im == "Y":
try:
try:
os.system("pip install paramiko")
except:
os.system("pip3 install paramiko")
except:
print("Please install paramiko package manually")
else:
print("Rerun and type 'y' to install")
#Running paramiko module with interactive password sending function
#this function helps to send password when sudo command is executed
def sudossh():
host = "type host ip"
port = 22
username = "type username"
password = "type password"
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
ssh.get_transport()
#In this example we will run HTTP module on server in port 80
command = "sudo su -c 'sudo python -m SimpleHTTPServer 80'"
print(f"Running: {command}\n")
stdin, stdout, stderr = ssh.exec_command(command=command,get_pty=True)
stdin.write("password\n")
print("sent password\n")
print("HTTP service is running now\n")
stdin.flush()
if stderr.channel.recv_exit_status() != 0:
print(f"Error: {stderr.readlines()}")
else:
print(f"Output: \n{stdout.readlines()}")
ssh.close()
except Exception as err:
print(str(err));
print("Thanks for using my application");
#Running another paramiko module with interactive password sending function
def grepverification():
host = "type host ip"
port = 22
username = "type username"
password = "type password"
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
ssh.get_transport()
#Open new session and check port 80 status on server
command = "sudo su -c 'netstat | grep 80'"
print(f"Running: {command}\n")
stdin, stdout, stderr = ssh.exec_command(command=command,get_pty=True)
stdin.write("password\n")
print("sent password\n")
print("Connection is established. Check below output\n")
stdin.flush()
if stderr.channel.recv_exit_status() != 0:
print(f"Error: {stderr.readlines()}")
else:
print(f"Output: \n{stdout.readlines()}")
ssh.close()
except Exception as err:
print(str(err));
print("Thanks for using my application");
def main():
#Multithreading helps to run both at a same time. Useful for verification.
# creating thread
th1 = threading.Thread(target=sudossh)
th2 = threading.Thread(target=grepverification)
# starting thread 1
th1.start()
# starting thread 2
th2.start()
# wait until thread 1 is completely executed
th1.join()
# wait until thread 2 is completely executed
th2.join()
# both threads completely executed
print("Completed!")
#you can use for loop to reduce lines but for understanding & smooth multithreading process will keep it as separate functions
#Comments are welcome. Thanks. Follow me on https://www.linkedin.com/in/dinesh-kumar-palanivelu-858441128/
#you need to change line - 23-26,36,51-54,64
if __name__=='__main__':
main()
在我的情况下,我需要在一个服务器上执行命令,这个服务器有一个特定的IP地址和端口。完成这些命令后,我还需要通过SFTP连接到另一个IP和不同的端口。条件是,在进行SFTP连接到另一个IP的时候,第一个连接必须保持活着,因为需要进行端口转发。
这两个连接单独使用时都能正常工作,但当我试图把这两个连接结合在一起时,第二个SFTP连接就无法正常工作了。
你需要把这些调用放到不同的线程里(或者进程,不过那样有点过于复杂),这就要求你的代码要放在一个函数里(这样做其实是个好主意:不要在模块的顶层写太多代码)。
比如说:
import sys, os, string, threading
import paramiko
cmd = "grep -h 'king' /opt/data/horror_20100810*"
outlock = threading.Lock()
def workon(host):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username='xy', password='xy')
stdin, stdout, stderr = ssh.exec_command(cmd)
stdin.write('xy\n')
stdin.flush()
with outlock:
print stdout.readlines()
def main():
hosts = ['10.10.3.10', '10.10.4.12', '10.10.2.15', ] # etc
threads = []
for h in hosts:
t = threading.Thread(target=workon, args=(h,))
t.start()
threads.append(t)
for t in threads:
t.join()
main()
如果你有超过五个主机,我建议你使用“线程池”架构和一个工作队列。但对于只有五个主机的情况,使用“专用线程”模型会更简单(尤其是因为标准库里没有线程池,所以你需要用像threadpool这样的第三方包……或者自己写很多复杂的代码,当然;-)。