目录
简介-paramiko
Python中实现远程连接需要用到外部模块,主要有paramiko,pexpect等。
paramiko主要执行远程连接和文件传输(即SSHClient和SFTPClinet),非Python自带,需要手动安装。
安装paramiko
pip install --upgrade pip #更新pip版本
pip install paramiko #安装
使用paramiko进行SSH连接
def SshSingle():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 设置白名单
ssh.connect(hostname='192.168.222.128, username='root', password='123456', port='22')
stdin, stdout, stderr = ssh.exec_command("ls -l /root")
# 标准格式输入、输出、错误
res, err = stdout.read(), stderr.read()
result = res if res else err
print(result.decode())
# 输出结果
ssh.close()
set_missing_host_policy方法是将SSH连接的KEY保存到know_hosts中,采用AutoAddPolicy()是自动为你保存的意思不需要手动输入yes来建立信任。具体使用及其他方法使用规则请参考官方文档。
多线程进行SSH连接见后下文
使用paramiko进行文件传输
def DloadUpload():
sftp = paramiko.Transport(sock=('192.168.222.128', 22))
sftp.connect(username='root', password='123456')
files = paramiko.SFTPClient.from_transport(sftp)
#
try:
# Download
# files.get("~/test.tx", "C:/Users/boy/Desktop/new.txt")
# get中前面为远程服务器文件路径及文件名,后面为下载到本地的路径及文件名
# 用例中本地平台为Windows
# Upload
files.put("C:/Users/boy/Desktop/shell.txt", "/root/shell")
# put中前面为本地文件路径及文件名,后面为上传到远程服务器的路径及文件名
# filelist = files.listdir("/root/")
# for f in filelist:
# files.get(os.path.join("/root/", f), os.path.join("C:/Users/boy/Desktop/", f)
except Exception as result:
print(result)
sftp.close()
SFTPClient类其他方法介绍:
listdir,获取远程SFTP服务端指定目录列表,如批量下载一个目录下的所有文件,上述代码注释部分;
mkdir,在SFTP服务端创建目录;
remove,删除SFTP服务端指定目录;
stat,获取远程SFTP服务端指定文件信息
与shell交互使用
def SshShell():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='192.168.222.128', username='root', password='123456', port='22')
shell = ssh.invoke_shell()
shell.settimeout(1)
# cmd = input()
# shell.send(cmd + '\r')
while True:
time.sleep(0.5)
# 设置睡眠时间以打印返回结果
recv = shell.recv(10240).decode()
if recv:
print(recv)
cmd = input()
if cmd == 'quit': #当输入quit时退出交互
break
else:
shell.send(cmd + '\n')
ssh.close()
补充
利用多线程进行SSH连接
pool = [dict(host='192.168.222.128', username='root', password='123456', port='22'),
dict(host='192.168.222.129', username='root', password='123456', port='22'),
dict(host='192.168.222.130', username='root', password='123456', port='22')
]
# 定义一个IP池
class SshThreading(threading.Thread):
# 封装
def __init__(self, cmd, host, username, password, port):
self.cmd = cmd
self.host = host
self.username = username
self.password = password
self.port = port
super(SshThreading, self).__init__()
def run(self):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=self.host, username=self.username, password=self.password, port=self.port)
stdin, stdout, stderr = ssh.exec_command(self.cmd)
res, err = stdout.read(), stderr.read()
result = res if res else err
print("[ip:%s] \n%s" % (self.host, self.cmd))
print(result.decode())
ssh.close()
def SshMUti():
cmd = "ls -l /root"
thread_pool = []
for host in pool:
t = SshThreading(host=host.get("host"),
username=host.get("username"),
password=host.get("password"),
port=host.get("port"),
cmd=cmd
)
# print(host.get("password"))
thread_pool.append(t)
for t in thread_pool:
t.start()
FTP传输文件
与FTP服务器进行文件传输,需要ftplib包
from ftplib import FTP
def FtpDownFile(allfile):
a = []
for f in allfile:
a.append(f)
# 可以先判断a是否不为空
for i in range(len(a)):
file_handler = open('C:/Users/boy/Desktop/' + a[i], 'wb').write
# 确保写入目录用户具有写权限
ftp.retrbinary('RETR %s' % a[i], file_handler)
def FtpUpFile():
file = open('C:/Users/boy/Desktop/123.txt', 'rb')
ftp.storbinary('STOR %s' % '123.txt', file)
file.close()
if __name__ == '__main__':
ftp = FTP()
ftp.encoding = 'utf-8'
ftp.connect(host='192.168.222.128', port=21)
ftp.login("root", "123456")
print(ftp.welcome)
print('\n')
ftp.cwd("/var/ftp/pub/")
all_file = ftp.nlst()
# FtpDownFile(all_file) #下载
FtpUpFile() #上传
ftp.close()
exit()