#基于ssh,用于连接远程服务器做操作:远程执行命令,上传或下载文件
import paramiko
#创建一个ssh对象
client = paramiko.SSHClient()
#2.解决问题:首次连接,会出现
# Are you sure you want to continue connecting (yes/no)? yes
# 自动选择yes
# 允许连接不在know_hosts文件中的主机
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#3.连接服务器
client.connect(hostname="172.25.254.19",port=22,username="root",password="westos")
#4.执行操作
stdin,stdout,stderr = client.exec_command("hostname")#标准输入,标准输出,标准错误输出。
#Execute a command on the SSH server. A new `.Channel` is opened and
# the requested command is executed. The command"s input and output
# streams are returned as Python ``file``-like objects representing
# stdin, stdout, and stderr.
#5.获取命令的执行结果
res = stdout.read().decode("utf-8")#使结果具有可读性
print(res)
#6.断开连接
client.close()
import paramiko
from paramiko.ssh_exception import NoValidConnectionsError, AuthenticationException
def conn(cmd,hostname,port=22,username="root"):
client = paramiko.SSHClient()
private_key = paramiko.RSAKey.from_private_key_file("id_rsa")#id_rsa存放私钥
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=hostname,
port=port,username=username,pkey=private_key)
except NoValidConnectionsError as e:
print("...连接失败...")
except AuthenticationException as e:
print("...密码错误...")
else:
stdin, stdout, stderr = client.exec_command(cmd)
result = stdout.read().decode("utf-8")
print(result)
finally:
client.close()
if __name__=="__main__":
for count in range(13,20):
hostname = "172.25.254.%s" %(count)
print("正在连接主机:",hostname)
conn("hostname",hostname)
print("...连接结束...")
基于用户名密码上传下载文件
sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的网络的加密方法。
import paramiko
tran = paramiko.Transport("172.25.254.19",22)
tran.connect(username="root",password="westos")
sftp = paramiko.SFTPClient.from_transport(tran)
#class SFTPClient(BaseSFTP, ClosingContextManager)
#SFTP client object.
# Used to open an SFTP session across an open SSH `.Transport` and perform
# remote file operations.
# Instances of this class may be used as context managers.
sftp.put("/home/kiosk/PycharmProjects/day18/07_pratice.py","/mnt/practice.py")
sftp.get("/mnt/passwd","hallo")
tran.close()
paramiko再封装
使paramiko模块执行自己想要的操作
import paramiko
import os
from paramiko.ssh_exception import NoValidConnectionsError, AuthenticationException, SSHException
class SshRrmote(object):
def __init__(self,cmd,hostname,port,username,passwd):
self.hostname = hostname
self.passwd = passwd
self.cmd = cmd
self.username = username
self.port = port
def run(self):
"""默认调用的内容"""
# cmd hostname
# put local_file remote_file
# get remote_file local_file
cmd_str = self.cmd.split()[0] # cmd
# 类的反射, 判断类里面是否可以支持该操作?
if hasattr(self, "do_" + cmd_str): # do_cmd
getattr(self, "do_" + cmd_str)()
else:
print("目前不支持该功能")
def do_cmd(self):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=self.hostname,port=int(self.port),username=self.username,password=self.passwd)
except NoValidConnectionsError as e:
print("...连接失败...")
except AuthenticationException as e:
print("...密码错误...")
else:
cmd = " ".join(self.cmd.split()[1:])
stdin, stdout, stderr = client.exec_command(cmd)
result = stdout.read().decode("utf-8")
print("执行结果",result)
finally:
print("断开%s的连接" %(self.hostname))
client.close()
def do_get(self):
#有待改进,因为连接多个主机时,会覆盖文件
print("开始下载")
trans = paramiko.Transport(self.hostname,int(self.port))
trans.connect(username=self.username,password=self.passwd)
print("hello")
except SSHException as e:
print("连接失败")
else:
sftp = paramiko.SFTPClient.from_transport(trans)
cmd = self.cmd.split()[1:]
if len(cmd)==2:
sftp.get(cmd[0],cmd[1])
print("下载文件%s成功,并保存为%s" %(cmd[0],cmd[1]))
else:
print("参数有误")
trans.close()
def do_put(self):
# put /tmp/passwd /tmp/passwd # 将本机的/tmp/passwd文件上传到远程主机的/tmp/passwd;
print("开始上传") #注意你使用的用户是否为kiosk
trans = paramiko.Transport(self.hostname, int(self.port))
trans.connect(username=self.username, password=self.passwd)
except SSHException as e:
print("连接失败")
else:
sftp = paramiko.SFTPClient.from_transport(trans)
cmd = self.cmd.split()[1:]
if len(cmd) == 2:
sftp.put(cmd[0],cmd[1])
print("上传文件%s成功,并保存为%s" %(cmd[0], cmd[1]))
else:
print("参数有误")
trans.close()
#1.选择要操作的主机组:mysql,web,ftp
# 主机信息怎么存?将不同的主机信息存放在不同的文件中
#2.根据选择的主机组,显示包含的主机IP/主机名
#3.让用户确认信息,选择需要批量执行的命令
# -cmd shell命令
# -put 本地文件 远程文件
# -get 远程文件 本地文件
def main():
groups = [file.rstrip(".conf") for file in os.listdir("conf")]
print("主机组显示".center(50,"*"))
[print(" ",item) for item in groups]
choiceGroup = input("请选择批量操作的主机组(eg:web):")
with open("conf/"+choiceGroup+".conf") as f:
info = f.readlines()
print("批量执行脚本".center(50, "*"))
while True:
cmd = input(">>").strip()
if cmd:
if cmd =="exit":
print("连接执行结束")
break
for item in info:
item=item.strip()
print(item.split(":")[0].center(50,"-"))
hostname,port,username,passwd = item.split(":")
ssh = SshRrmote(cmd,hostname,port,username,passwd)
ssh.run()
main()