Python | paramiko的概念及其使用
本文主要介绍 paramiko
的概念及其使用 1’ 2’ 3‘ 4。
本文环境 Centos 7.9
, Python 3.7
, Paramiko 2.7.2
。
Last Updated: 2022 / 9 / 9
Python | paramiko的概念及其使用
- 概念
- 安装
- Linux
- 问题
- windows
- 使用
- 单线程
- SSH
- 连接
- SSHClient
- 语法
- 应对策略
- 执行命令
- 语法
- SSH服务端的实现
- 示例
- 基于用户名和密码登录
- 基于公钥密钥登录
- SFTP
- 连接
- Transport
- 语法
- 上传 / 下载
- 文件
- 文件夹
- 执行命令
- 语法
- Xshell-like功能
- 输入命令后立马返回结果
- tab自动补全
- 示例
- 基于用户名和密码登录
- 基于公钥密钥登录
- 多线程
- SSH
- 参考链接
概念
paramiko
5 是用 python
语言写的一个模块,遵循 SSH2
协议 (底层使用 cryptography
),支持以加密和认证的方式,进行远程服务器的连接。
由于使用的是 python
这样的能够跨平台运行的语言,所以所有 python
支持的平台,如 Linux
, Solaris
, BSD
, MacOS X
, Windows
等,paramiko
都可以支持,因此,如果需要使用 SSH
从一个平台连接到另外一个平台,进行一系列的操作时,paramiko
是最佳工具之一。
举个常见的例子,现有这样的需求:需要使用 windows
客户端,远程连接到 Linux
服务器,查看上面的日志状态,大家通常使用的方法会是:
- 用
telnet
; - 用
PUTTY
; - 用
WinSCP
; - 用
XManager
等;
那现在如果需求又增加一条,要从服务器上下载文件,该怎么办?那常用的办法可能会是:
Linux
上安装FTP
并配置 ;Linux
上安装Sambe
并配置 ;
大家会发现,常见的解决方法都会需要对远程服务器必要的配置,如果远程服务器只有一两台还好说,如果有N台,还需要逐台进行配置,或者需要使用代码进行以上操作时,上面的办法就不太方便了。
使用 paramiko
可以很好的解决以上问题。比起前面的方法,它仅需要在本地上安装相应的软件(python
以及 PyCrypto
),对远程服务器没有配置要求,对于连接多台服务器,进行复杂的连接操作特别有帮助,可以在 Python
代码中直接使用 SSH
协议对远程服务器执行操作,而不是通过 ssh
命令对远程服务器进行操作,比如连接远程服务器、执行命令和上传、下载文件的功能。。
安装
安装 paramiko
有两个先决条件,python
和另外一个名为 PyCrypto
的模块。
Linux
通常安装标准的 python
模块,只需要在模块的根目录下运行:
python setup.py build
python setup.py install
或者,
pip install xxx
paramiko
和 PyCrypto
也不例外,唯一麻烦的就是安装 PyCrypto
时,需要 GCC
库编译,如果没有 GCC
库会报错,会导致 PyCrypto
以及 paramiko
无法安装。
如果是离线安装 6,需要先准备好所有相关的依赖包(bcrypt
、cffi
、cryptography
、pycparser
、PyNaCl
、six
),这些依赖包都可以在 https://pypi.org/
上搜到 6。
离线安装顺序很重要,装下一个是基于上一个,大概顺序是:pycparse
-> cffi
(libffi-devel
是前提依赖 7’ 8’ 9’ 10‘ 11) -> bcrypt
-> six
-> pynacl
-> asnlcrypto
-> cryptography
(openssl-devel
是前提依赖 12’ 13‘ 14’ 15’ 16‘ 17) -> paramiko
18。
如果你装的时候包已经有更新的版本了,可以先找一台可以联网的电脑,记录下它从网上下载的文件记录,然后去找对应的包下载下来,拷到无法联网的电脑上随便什么顺序安装即可。
安装完成后可以在终端中输入 python -c "import paramiko"
, 如果没有报错则说明安装成功。
问题
- 如果出现未知异常,比如提示信息说
serialization.Encoding.Raw in kex_curve25519.py
, 可能是由于依赖库之一的cryptography
的版本问题 19。
windows
以下以32 位的 windows XP
为例,说明 paramiko
的安装过程:
- 安装python,
2.2
以上版本都可以,安装过程略,并假设安装目录是c:\python
; - 判断本地是否安装了
GCC
,并在PATH
变量可以找到。
如果没有,可使用windows
版的GCC
,即MinGW
,下载地址为http://sourceforge.net/projects/mingw/
,然后运行下载后的exe
文件进行网络安装,假设目录为C:\mingw
,在PATH
中加入C:\mingw\bin
,并在c:\python\lib\distutils
下新建一个名称是distutils.cfg
的文件,填入:
[build]
compiler=mingw32
- 下载
PyCrypto
,地址是https://www.dlitz.net/software/pycrypto/
安装PyCrypto的步骤为,解压缩,在dos
下进入解压缩的目录,运行
C:\python\python.exe setup.py build
C:\python\python.exe setup.py install
测试 paramiko
, 运行 python.exe
,在提示符下输入 Import paramiko
。如果没有出现错误提示,说明 paramiko
安装成功
使用
单线程
SSH
连接
SSHClient
语法
client = paramiko.SSHClient.connect(hostname,port=SSH_PORT,username=None,password=None,pkey=None,key_filename=None,timeout=None,allow_agent=True,look_for_keys=True,compress=False,sock=None,gss_auth=False,gss_kex=False,gss_deleg_creds=True,gss_host=None,banner_timeout=None,auth_timeout=None,gss_trust_dns=True,passphrase=None,disabled_algorithms=None,
)
参数 | 含义 |
---|---|
hostname
|
连接的目标主机。 |
port=SSH_PORT
|
指定端口 20 |
username=None
|
验证的用户名 |
password=None
|
验证的用户密码 |
pkey=None
|
私钥方式用于身份验证 |
key_filename=None
|
一个文件名或文件列表,指定私钥文件 |
timeout=None
|
可选的 tcp 连接超时时间
|
allow_agent=True
|
是否允许连接到 ssh 代理,默认为 True 允许
|
look_for_keys=True
|
是否在 ~/.ssh 中搜索私钥文件,默认为 True 允许
|
compress=False
|
是否打开压缩 |
应对策略
ssh.set_missing_host_key_policy()
设置连接的远程主机没有本地主机密钥或 HostKeys
对象时的策略,目前支持三种:
AutoAddPolicy
自动添加主机名及主机密钥到本地HostKeys
对象,不依赖load_system_host_key
的配置。即新建立ssh
连接时不需要再输入yes
或no
进行确认;WarningPolicy
用于记录一个未知的主机密钥的python
警告。并接受,功能上和AutoAddPolicy
类似,但是会提示是新连接;RejectPolicy
自动拒绝未知的主机名和密钥,依赖load_system_host_key
的配置。此为默认选项;
执行命令
语法
exec_command(command,bufsize=-1,timeout=None,get_pty=False,environment=None,
)
参数 | 含义 |
---|---|
command
|
可以任意 linux 支持的命令,如一些常用的命令:
|
SSH服务端的实现
实现 SSH
服务端必须继承 ServerInterface
,并实现里面相应的方法。具体代码如下:
import socket
import sys
import threading
import paramikohost_key = paramiko.RSAKey(filename='private_key.key')class Server(paramiko.ServerInterface):def __init__(self):#执行start_server()方法首先会触发Event,如果返回成功,is_active返回Trueself.event = threading.Event()#当is_active返回True,进入到认证阶段def check_auth_password(self, username, password):if (username == 'root') and (password == '123456'):return paramiko.AUTH_SUCCESSFULreturn paramiko.AUTH_FAILED#当认证成功,client会请求打开一个Channeldef check_channel_request(self, kind, chanid):if kind == 'session':return paramiko.OPEN_SUCCEEDED
#命令行接收ip与port
server = sys.argv[1]
ssh_port = int(sys.argv[2])#建立socket
try:sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP socketsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)sock.bind((server, ssh_port)) sock.listen(100) print '[+] Listening for connection ...'client, addr = sock.accept()
except Exception, e:print '[-] Listen failed: ' + str(e)sys.exit(1)
print '[+] Got a connection!'try:#用sock.accept()返回的socket实例化TransportbhSession = paramiko.Transport(client)#添加一个RSA密钥加密会话bhSession.add_server_key(host_key)server = Server()try:#启动SSH服务端bhSession.start_server(server=server)except paramiko.SSHException, x:print '[-] SSH negotiation failed'chan = bhSession.accept(20) print '[+] Authenticated!'print chan.recv(1024)chan.send("Welcome to my ssh")while True:try:command = raw_input("Enter command:").strip("\n") if command != 'exit':chan.send(command)print chan.recv(1024) + '\n'else:chan.send('exit')print 'exiting'bhSession.close()raise Exception('exit')except KeyboardInterrupt:bhSession.close()
except Exception, e:print '[-] Caught exception: ' + str(e)try:bhSession.close()except:passsys.exit(1)
示例
参考此处 2’ 21‘ 22
基于用户名和密码登录
ssh = paramiko.SSHClient()
# 实例化SSHClient,新建client对象ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 自动添加策略,保存服务器的主机名和密钥信息进入host_allow列表,此方法必须放在connect方法的前面。
# 如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接ssh.connect(hostname='192.168.1.1', port=22, username='root', password='123456')
# 调用connect()方法连接SSH服务端,以用户名和密码进行认证stdin, stdout, stderr = client.exec_command('df -h ')
# stdout 为正确输出,stderr为错误输出,同时是有1个变量有值
# 打开一个Channel并执行命令print(stdout.read().decode('utf-8'))
# print(stdout.readlines())
# 打印执行结果client.close()
# 关闭SSHClient
stdin
无法被read()
,它是input
, 而非output
,否则将会报出"File is not open for reading"
23。
基于公钥密钥登录
以上需要确保被访问的服务器对应用户 .ssh
目录下有authorized_keys
文件,也就是将服务器上生成的公钥文件保存为authorized_keys
。并将私钥文件作为 paramiko
的登陆密钥。
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数ssh = paramiko.SSHClient()
# 建立连接
ssh.connect(hostname='192.168.2.129',port=22,username='super',pkey=pkey)stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())
# 执行命令, 结果放到stdout中,如果有错误将放到stderr中ssh.close()
# 关闭连接
SFTP
参考此处 3’ 21
连接
Transport
SSHClient
是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,SSHClient
则无法实现,可以通过如下方式来操作:
语法
t = paramiko.Transport(('192.168.2.129', 22))
# 实例化一个trans对象# 实例化一个transport对象t.connect(username='super', password='super')
# 建立连接sftp = paramiko.SFTPClient.from_transport(t)
# 实例化一个 sftp对象,指定连接的通道
上传 / 下载
文件
传输单个文件的方法为 get
或 put
,但每次只能传输一个文件,而不是整个目录。
比如,传输单个文件的示例如下:
t = paramiko.Transport(('192.168.2.129', 22))
# 实例化一个trans对象# 实例化一个transport对象t.connect(username='super', password='super')
# 建立连接sftp = paramiko.SFTPClient.from_transport(t)
# 实例化一个 sftp对象,指定连接的通道sftp.put(localpath='/tmp/11.txt', remotepath='/Desktop/22.txt')
# 发送文件
# 将本地tmp文件夹下的22.txt put到远端Desktop文件夹并保存为22.txtsftp.get(remotepath='Desktop/22.txt', localpath='tmp/11.txt')
# 下载文件
# 将远端的Desktop文件夹下的22.txt get到本地tmp文件夹并保存为11.txtt.close()
# 关闭连接
上面的 remotepath
和 localpath
一定是文件的路径,不能是目录路径。
文件夹
如何传输整个目录?24’ 25’ 26
有两种思路:
- 如果是要
get
则采用connect
方法连接到linux主机,然后通过send
方法执行tar
命令将需要传输的整个目录打包,再传输打包后的文件即可,如果是put
则需在本地打包。
- 缺点
在远端或者本地进行打包或者解压,并且打包会占用临时存储空间,如果是远端打包还需先
SSH
连接 linux主机。
- 优点
不用做目录扫描处理。
- 遍历需要
get
或put
的目录及其子目录,然后依次传输每一个文件。
- 优点
不需要
SSH
登陆和打包解压。
- 缺点
需要做目录扫描,但是目录扫描是很简单的,因此我们采用这种方法。
由于要扫描目录,因此先定义一个方法用来对指定目录进行扫描,找出该目录及所有子目录中的所有文件。
那么,怎么扫描目录呢?使用 python
的 os
库的方法吗?肯定是不行的,因为 python
的 os
库的方法都是对本地目录或文件的操作,它是无法操作远程linux
主机上的文件和目录的。
但是 paramiko
的 SFTP
接口提供了操作远端 linux
主机上的文件和目录的方法,只要建立了与远端的SFTP
连接后,就可以执行文件和目录操作。
import paramiko
import statt = paramiko.Transport(('192.168.2.129', 22))
t.connect(username='YourUsername', password='YourPassword')
sftp = paramiko.SFTPClient.from_transport(t)remote_dir = '/Desktop/Downloads/paho-mqtt-1.5.1'def get_file_list_in_remote_dir(sftp, remote_dir):file_list = list()if remote_dir[-1] == '/':remote_dir = remote_dir[0:-1]files = sftp.listdir_attr(remote_dir)for file in files:filename = remote_dir + '/' + file.filenameif stat.S_ISDIR(file.st_mode):file_list.extend(get_file_list_in_remote_dir(sftp, filename))if stat.S_ISREG(file.st_mode):file_list.append(filename)return file_listfile_list = get_file_list_in_remote_dir(sftp=sftp, remote_dir=remote_dir)
在上面的方法中,sftp
表示已经建立的 sftp
连接,remote_dir
是要扫描的远端目录。
在扫描目录的时候,使用的 sftp.listdir_attr
方法会列出指定目录下的所有文件或目录,并且还会列出其属性,比如st_size
, st_uid
, st_gid
, st_mode
, st_atime
, st_mtime
。这些属性与 linux
中的 stat
函数返回的属性类似,我们就是根据其中的 st_mode
属性来判断是一个目录还是文件,并且处理 st_mode
的方法(位于 stat
模块中)也是与 linux
中定义的宏一致的。
获取到指定目录下的所有文件之后,传输就比较简单了,依次遍历 get
即可:
import paramiko
import stat
import ost = paramiko.Transport(('192.168.2.129', 22))
t.connect(username='YourUsername', password='YourPassword')
sftp = paramiko.SFTPClient.from_transport(t)remote_dir = '/Desktop/Downloads/paho-mqtt-1.5.1'
local_dir = 'D:\\Test'def get_file_list_in_remote_dir(sftp, remote_dir):file_list = list()if remote_dir[-1] == '/':remote_dir = remote_dir[0:-1]files = sftp.listdir_attr(remote_dir)for file in files:filename = remote_dir + '/' + file.filenameif stat.S_ISDIR(file.st_mode):file_list.extend(get_file_list_in_remote_dir(sftp, filename))if stat.S_ISREG(file.st_mode):file_list.append(filename)return file_listdef get_dir(sftp, remote_dir, local_dir):file_list = get_file_list_in_remote_dir(sftp, remote_dir)for file in file_list:file_subdir = os.path.dirname(file).split(remote_dir)[-1]file_subdir = file_subdir.replace('/', '\\')file_name = os.path.basename(file)local_filedir = local_dir + file_subdirlocal_filename = local_filedir + '\\' + file_nameif not os.path.exists(local_filedir):os.makedirs(local_filedir)sftp.get(file, local_filename)get_dir(sftp, remote_dir, local_dir)
上面方法将 remote_dir
目录中的所有文件都按与远端一致的目录结构 get
到了本地 local_dir
目录中。
下面再来看看 put
,其实与 get
几乎一样,现在扫描本地目录,然后依次遍历文件并 put
到远端 27。
由于是对本地目录做扫描,因此不需要调用 SFTP
中的文件目录处理接口了,直接使用 python
的 os
库即可,代码如下:
import paramiko
import stat
import ost = paramiko.Transport(('192.168.2.129', 22))
t.connect(username='YourUsername', password='YourPassword')
sftp = paramiko.SFTPClient.from_transport(t)local_dir = 'D:\\Test'
remote_dir = '/Desktop/Downloads/paho-mqtt-1.5.1'def get_file_list_in_local_dir(sftp, local_dir):file_list = list()files = os.listdir(local_dir)for file in files:filename = os.path.join(local_dir, file)if os.path.isdir(filename):file_list.extend(get_file_list_in_local_dir(sftp, filename))else:file_list.append(filename)return file_listdef put_dir(sftp, local_dir, remote_dir):file_list = get_file_list_in_local_dir(sftp, local_dir)for file in file_list:file_subdir = os.path.dirname(file).split(local_dir)[-1]file_subdir = file_subdir.replace('\\', '/')file_name = os.path.basename(file)remote_filedir = remote_dir + file_subdirif remote_filedir.endswith('/'):remote_filedir = remote_filedir[0:-1]remote_filename = remote_filedir + '/' + file_nametry:sftp.stat(remote_filedir)except:sftp.mkdir(remote_filedir)sftp.put(file, remote_filename, confirm=True)put_dir(sftp, local_dir=local_dir, remote_dir=remote_dir)
执行命令
语法
exec_command(command,bufsize=-1,timeout=None,get_pty=False,environment=None,
)
参数 | 含义 |
---|---|
command
|
可以任意 linux 支持的命令,如一些常用的命令:
|
Xshell-like功能
注意,在 windows
中,sys.stdin
不是一个 socket
或者 file-like
对象,而是一个 PseudoOutputFile
对象,不能被 select
处理。所以上面的脚本不能在 windows
中运行,只能用于 linux
。
输入命令后立马返回结果
import paramiko
import os
import select
import sys# 建立一个socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 启动一个客户端
trans.start_client()# 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='super', password='super')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell()
# 下面就可以执行你所有的操作,用select实现
# 对输入终端sys.stdin和 通道进行监控,
# 当用户在终端输入命令后,将命令交给channel通道,这个时候sys.stdin就发生变化,select就可以感知
# channel的发送命令、获取结果过程其实就是一个socket的发送和接受信息的过程
while True:readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])# 如果是用户输入命令了,sys.stdin发生变化if sys.stdin in readlist:# 获取输入的内容input_cmd = sys.stdin.read(1)# 将命令发送给服务器channel.sendall(input_cmd)# 服务器返回了结果,channel通道接受到结果,发生变化 select感知到if channel in readlist:# 获取结果result = channel.recv(1024)# 断开连接后退出if len(result) == 0:print("\r\n**** EOF **** \r\n")break# 输出到屏幕sys.stdout.write(result.decode())sys.stdout.flush()# 关闭通道
channel.close()
# 关闭链接
trans.close()
tab自动补全
import paramiko
import os
import select
import sys
import tty
import termios'''
实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果
支持自动补全,直接调用服务器终端'''
# 建立一个socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 启动一个客户端
trans.start_client()# 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='super', password='super')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell()# 获取原操作终端属性
oldtty = termios.tcgetattr(sys.stdin)
try:# 将现在的操作终端属性设置为服务器上的原生终端属性,可以支持tab了tty.setraw(sys.stdin)channel.settimeout(0)while True:readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])# 如果是用户输入命令了,sys.stdin发生变化if sys.stdin in readlist:# 获取输入的内容,输入一个字符发送1个字符input_cmd = sys.stdin.read(1)# 将命令发送给服务器channel.sendall(input_cmd)# 服务器返回了结果,channel通道接受到结果,发生变化 select感知到if channel in readlist:# 获取结果result = channel.recv(1024)# 断开连接后退出if len(result) == 0:print("\r\n**** EOF **** \r\n")break# 输出到屏幕sys.stdout.write(result.decode())sys.stdout.flush()
finally:# 执行完后将现在的终端属性恢复为原操作终端属性termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)# 关闭通道
channel.close()
# 关闭链接
trans.close()
示例
基于用户名和密码登录
t = paramiko.Transport(('192.168.2.129', 22))
# 实例化一个transport对象t.connect(username='super', password='super')ssh = paramiko.SSHClient()
ssh._transport = t
# 将sshclient的对象ssh的transport指定为以上的tstdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())
# 执行命令,和传统方法一样t.close()
# 关闭连接
基于公钥密钥登录
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数# 建立连接
t = paramiko.Transport(('192.168.2.129', 22))
t.connect(username='super', pkey=pkey)ssh = paramiko.SSHClient()
ssh._transport = t
# 将sshclient的对象的transport指定为以上的transstdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())
# 执行命令,和传统方法一样t.close()
# 关闭连接
t = paramiko.Transport((“主机”,”端口”))
# 实例化一个传输对象t.connect(username = “用户名”, password = “口令”)
# 建立连接。如果连接远程主机需要提供密钥,上面第二行代码可改成:
# t.connect(username = “用户名”, password = “口令”, hostkey=”密钥”)sftp = paramiko.SFTPClient.from_transport(transport)
# 将实例Transport作为参数传入SFTPClient中sftp.put(r'E:\Users\Desktop\test.txt','/opt/test1.txt')
# 将本地桌面test.txt文件上传至虚拟机opt目录下sftp.get('/opt/test2.txt',r'E:\Users\Desktop\test2.txt')
# 将虚拟机opt目录下test2.txt下载到本地桌面t.close()
#关闭连接
f’ ‘:格式化
r’ ‘:去除转义
b’ ‘:指定为字节类型
u’ ':指定为Unicode编码
多线程
SSH
#!/usr/bin/env python3
import sys
import paramiko
import threading
import osdef remote_comm(host, pwd, command):'''创建函数实现远程连接主机、服务器密码以及在远程主机上执行的命令的功能:param host::param pwd::param command::return:'''ssh = paramiko.SSHClient()# 创建用于连接ssh服务器的实例ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 设置自动添加主机密钥try:ssh.connect(hostname=host, username='root', password=pwd)# 连接ssh服务器,添加连接的主机、用户名、密码填好,捕获异常,有异常则跳出函数except:returnstdin, stdout, stderr = ssh.exec_command(command)# 在ssh服务器上执行指定命令,返回3项类文件对象,分别是,输入、输出、错误out = stdout.read() # 读取输出error = stderr.read() # 读取错误if out: # 如果有输出print('[%s] OUT:\n%s' % (host, out.decode('utf8')))# 打印主机输出内容if error: # 如果有错误print('[%s] ERROR:\n%s' % (host, error.decode('utf8')))# 打印主机错误信息ssh.close() # 程序结束if __name__ == '__main__':if len(sys.argv) != 3:# 设定sys.argv长度,确保remote_comm函数中参数数量print('Usage: %s ipaddr_file "command"' % sys.argv[0])exit(1)if not os.path.isfile(sys.argv[1]):# 判断命令行上输入如果不是文件,确保输入的是文件print('No such file:', sys.argv[1])exit(2)fname = sys.argv[1]# fname为存储远程主机ip的文件,用sys.argv方法,可以在执行脚本时再输入文件名,更为灵活command = sys.argv[2]# command为在远程主机上执行的命令,用sys.argv方法,可以在执行脚本时再输入相应命令,command为remote_comm函数第三个参数# 通过getpass输入远程服务器密码,pwd为remote_comm函数第二个参数# pwd = getpass.getpass()pwd='Taren1.bgsn'with open(fname) as fobj:# 打开存有远程主机ip的文件ips = [line.strip() for line in fobj]# 将遍历文件将ip以列表形式存入ips,line.strip()可以去掉每行ip后for ip in ips:# 循环遍历列表,获取ip地址,ip为remote_comm函数第一个参数# 将读取到的ip地址作为remote_comm函数实际参数传递给函数,ips中有几个ip地址循环几次t = threading.Thread(target=remote_comm, args=(ip, pwd, command))# 创建多线程t.start()# 启用多线程
详情需参考此处 2
参考链接
python使用paramiko实现ssh的功能详解 ↩︎
paramiko模块怎么在Python项目中使用 ↩︎ ↩︎ ↩︎
paramiko的安装与使用 ↩︎ ↩︎
paramiko 远程连接ssh ↩︎
paramiko ↩︎
windows下python3.7离线安装paramiko库全文件,亲测有用,太折腾人了 ↩︎ ↩︎
Installing cffi fails with c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory ↩︎
linux系统中离线安装python3.7过程记录 ↩︎
[小技巧] Linux 里快速安装缺少的库 ↩︎
Libffi-devel Download for Linux (eopkg, rpm, xbps) ↩︎
关于在centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named ‘_ctypes‘的解决办法 ↩︎
How to fix: fatal error: openssl/opensslv.h: No such file or directory in RedHat 7 ↩︎
Linux Ubuntu openssl离线源码安装、升级版本 ↩︎
Frequently asked questions ↩︎
Linux中的 openssl/opensslv.h找不到的问题解决 ↩︎
Openssl-devel Download for Linux (eopkg, pkg, rpm, xbps) ↩︎
Welcome to OpenSSL! ↩︎
Paramiko Docs ↩︎
paramiko.SSHClient.connect raises unknown exception ↩︎
IP地址、MAC地址以及端口号 ↩︎
paramiko模块使用方法(十二) ↩︎ ↩︎
^paramiko连接方式 ↩︎
Can’t get stderr with Paramiko ↩︎
使用paramiko的SFTP get或put整个目录 ↩︎
Python3-paramiko-SFTP上传文件夹到多台远程服务器 ↩︎
python之paramiko文件夹远程上传 ↩︎
paramiko怎么判断远程目录是否存在? ↩︎
Python | paramiko的概念及其使用相关推荐
- 2021-03-12 Python基础核心概念 变量和简单数据类型
Python基础核心概念 1 变量和简单数据类型 变量命名格式:变量名 = "赋值" 1.1 变量使用规范 使用变量时,需要遵守一些规则.违反这些规则将引发错误. ~变量名只能包含 ...
- python paramiko安装_Python Paramiko模块的安装与使用详解
一.前言 常见的解决方法都会需要对远程服务器必要的配置,如果远程服务器只有一两台还好说,如果有N台,还需要逐台进行配置,或者需要使用代码进行以上操作时,上面的办法就不太方便了.而使用paramiko可 ...
- python paramiko并发_使用Python paramiko模块利用多线程实现ssh并发执行操作
1.paramiko概述 ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography). 有了Paramiko以 ...
- 《Python数据挖掘:概念、方法与实践》——1.5节小结
本节书摘来自华章社区<Python数据挖掘:概念.方法与实践>一书中的第1章,第1.5节小结,作者[美] 梅甘·斯夸尔(Megan Squire),更多章节内容可以访问云栖社区" ...
- 《Python数据挖掘:概念、方法与实践》一2.4 小结
本节书摘来自华章出版社<Python数据挖掘:概念.方法与实践>一书中的第2章,第2.4节,作者[美] 梅甘·斯夸尔(Megan Squire),更多章节内容可以访问云栖社区"华 ...
- python异常(概念、捕获、传递、抛出)
python异常(概念.捕获.传递.抛出) 参考文章: (1)python异常(概念.捕获.传递.抛出) (2)https://www.cnblogs.com/xiangribai/p/8594392 ...
- python 线程 (概念+示例代码)
目录 1. 线程的概念 1.1 主线程 1.2 子线程 1.3 单线程与多线程基本示例代码 2. 线程的数量 3. 线程的参数 4. 守护线程 5. 并行和并发 5.1 多任务的概念 5.2 并发和并 ...
- python paramiko使用_python Paramiko使用示例
Paramiko 是由 Python 语言编写的一个扩展模块,提供了基于 SSHv2 协议 (包括客户端和服务端)的多种功能实现.通常被用来远程控制类 UNIX 系统. Paramiko 可以直接使用 ...
- python基础 python函数 函数概念 函数的多种参数 多种调用参数 装包 解包 函数代码块 函数的返回值
python基础 python函数 函数概念 函数的多种参数 多种调用参数 装包 解包 函数代码块 函数的返回值 一 .函数概念 函数是根据需要,将代码打包为代码块, 每一个代码块就可以封装为一个函数 ...
最新文章
- docker redis 多个实例
- 程序员带你解析Python3
- P8实战(四):多种分布式锁实现
- oc调用rest api
- 学习笔记:可持久化线段树(主席树):静态 + 动态
- python8皇后不攻击问题_python 八皇后问题的解法(深度搜索)
- C++Function Object Adapter之not1
- FFMPEG 常用命令行
- 安装高版本的java_运行“需要Java 11或更高版本”的Visual Studio代码。请下载并安装最新的JDK”...
- 自定义Cell引发的悲剧。。。。
- 数字图像处理及MATLAB实现实验四——图像变换
- 一起玩转CAN卡“第五通道”吧!
- 【智能制造】智能制造50大产业链全景图
- Air720UGUH 极简封装 LTE Cat.1 bis 模块[合宙通信]
- 网络流量分析之流量采集到流量还原
- 操作rabbitMQ时,误删guest账户,无法登录
- Show出你的高超技能 首届“中国高性能云计算创新大赛”要开赛啦!
- Java学习教程,Java从入门到精通,全套Java视频教程+笔记+配套工具
- matplotlib修改背景颜色和插入背景图片
- APP测试点总结(全面)
热门文章
- linux5挂载移动硬盘,RHEL5挂载NFTS格式移动硬盘的方法
- 安装操作系统的操作步骤
- 蓝桥杯真题 外卖店优先级(2019年省赛)
- 若依Ruoyi-Vue生成代码使用
- farpoint 小数保留4位_farpoint spread for windows forms 5怎么注册
- iOS逆向 越狱和安卓手机Root的区别
- 穿越火线项目知识——总线
- 未来集市未来怎么样_大流行后的未来
- 对计算机科技文化节的理解,人工智能学院科技文化节 | 文化凝聚力量,舞台放飞梦想...
- (六十一)线性模型:线性回归、岭回归和套索回归