使用 paramiko 类,可以实现python调用ssh
1. ftp上传下发文件
2. 执行ssh命令,但是无法一些环境变量无法执行如 cd $AU_TOP,会没有返回
每次执行shell命令后会关闭会话,下一次调用会打开新的会话,如果执行多条命令可以使用“;”做为分隔符,一次输入执行,如“cd ..;pwd”可以实现移动到上一次文件,打印路径;
使用 paramiko的exec_command来执行linux命令,不能执行shell,我需要执行ebs的xdf下载生成文件,exec_command会报错。后来发现paramiko-expect可以真实的执行linux命令,说明如下:
paramiko expect为paramiko ssh库提供类似expect的扩展 它允许脚本通过真正的ssh与主机完全交互 连接。
类是用ssh客户机对象构造的(这可能是 扩展以支持未来的运输以获得更大的灵活性。
官方文档路径:Client — Paramiko documentation
参考文档:paramiko详解_massoo1的博客-CSDN博客_paramiko
paramiko expect参考:Python paramiko-expect包_程序模块 - PyPI - Python中文网
paramiko expect例子:paramiko-expect/paramiko_expect-demo-helper.py at master · fgimian/paramiko-expect · GitHub
以下为例子:
getFtpfile和putFtpfile的路径为带文件路径,下载路径如果文件夹路径不存在,会报错,需要使用os类检查下,如果不存在则建立该路径。
import paramiko
class PySSH():
def __init__(self,ip,port,userName,passWord):
print('start')
self.ip = ip
self.port = port
self.userName = userName
self.passWord = passWord
#print('-->>' + self.ip+self.port+self.userName+self.passWord)
def executeCommand(self,command):
print(command)
#print(self.ip+self.port+self.userName+self.passWord)
try:
# 创建sshClient实例对象
ssh = paramiko.SSHClient()
# 设置信任远程机器,允许访问
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# set_missing_host_key_policy
'''
设置远程服务器没有在know_hosts文件中记录时的应对策略。目前支持三种策略:
AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
'''
except:
print("There is an error with the SSHClient")
try:
# 设置ssh远程连接机器,参数依次为地址、端口、用户名、密码,ssh端口默认22
print(self.ip,self.port,self.userName,self.passWord)
ssh.connect(self.ip,#"10.10.11.110",
self.port,#
self.userName,#"appndev",
self.passWord#"appndev"
)
# ssh.connect("10.10.11.110",
# "22",
# "appndev",
# "appndev")
'''
connect参数详解:
hostname 连接的目标主机,该项必填
port=SSH_PORT 指定端口
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密钥链接大家可以参考我的这篇博客:https://www.cnblogs.com/victoryhan/p/16417898.html
这里只专注于客户端Python代码的实现。
#导入私钥
privateKey = paramiko.RSAKey.from_private_key_file('./id_rsa')
ssh.connect('ip',22,'username',pkey=privateKey)
'''
'''
基于私钥字符串连接
#私钥字符串就是私钥的内容,位置在这篇博文里有介绍:https://www.cnblogs.com/victoryhan/p/16417898.html
keyStr = '[私钥内容]'
privateKey = paramiko.RSAKey(file_obj=StringIO(keyStr))
ssh.connect('ip','22','username',pkey=privateKey)
'''
print("success to connect to remote server")
except:
print("Failed to connect to remote server")
'''
执行linux命令
'''
try:
# 设置代表需要执行的linux命令的变量,多条命令用分号隔开
# order = "ls /"
#order = "pwd /"
# 每次执行命令会返回三个对象,对应标准输入、标准输出、标准错误。每调用一次exec_command方法就相当于重新打开一次linux终端,终端环境都是新的。
#stdin, stdout, stderr = ssh.exec_command(order)
stdin, stdout, stderr = ssh.exec_command(command)
# 如果使用了sudo命令请启用下面的代码并填入对应的密码
# stdin.write("passwd")
# stdin.flush()
# 打印输出结果
print(stdout.readlines())
# 打印命令执行错误信息
print(stderr.readlines())
print('success to carry out command')
except:
print('Fail to carry out command')
# 关闭ssh链接
ssh.close()
def getSftp(self):
transport = paramiko.Transport((self.ip, self.port)) # 注意啊,必须是数字22而不是'22',
print('print 1')
transport.connect(username=self.userName, password=self.passWord) # 需要 用username=和password=,如果只输入值的话,会报错
sftp = paramiko.SFTPClient.from_transport(transport)
return sftp#,transport
def closeSftp(self,transport):
transport.close()
#上传附件
def putFtpfile(self,fromPath,toPath):
transport = paramiko.Transport((self.ip, self.port)) # 注意啊,必须是数字22而不是'22',
print('print 1')
transport.connect(username=self.userName, password=self.passWord) # 需要 用username=和password=,如果只输入值的话,会报错
sftp = paramiko.SFTPClient.from_transport(transport)
#sftp = getSftp()
# 上传
# sftp.put('[localpath]','[remotepath]')
#sftp.put('D:\\Users\\brayden.liu\\Documents\\erp-items.txt', '/home/appndev/erp-items.txt')
sftp.put(fromPath, toPath)
transport.close()
#下载附件
def getFtpfile(self,fromPath,toPath):
transport = paramiko.Transport((self.ip, self.port)) # 注意啊,必须是数字22而不是'22',
print('print 1')
transport.connect(username=self.userName, password=self.passWord) # 需要 用username=和password=,如果只输入值的话,会报错
sftp = paramiko.SFTPClient.from_transport(transport)
# 下载
#sftp.get('/home/appndev/L8136560.log','D:\\Users\\brayden.liu\\Documents\\L8136560.log')
sftp.get(fromPath, toPath)
transport.close()
def putFtpDir(self,fromPath,toPath,name):
#确认ftp是否有该文件夹,没有则创建
try:
# 创建sshClient实例对象
ssh = paramiko.SSHClient()
# 设置信任远程机器,允许访问
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
except:
print("There is an error with the SSHClient")
try:
# 设置ssh远程连接机器,参数依次为地址、端口、用户名、密码,ssh端口默认22
print(self.ip,self.port,self.userName,self.passWord)
ssh.connect(self.ip,#"10.10.11.110",
"22",#self.port,#
self.userName,#"appndev",
self.passWord#"appndev"
)
print("success to connect to remote server")
except:
print("Failed to connect to remote server")
'''
执行linux命令
'''
try:
# 设置代表需要执行的linux命令的变量,多条命令用分号隔开
order = "ls /"
#order = "pwd /"
# 每次执行命令会返回三个对象,对应标准输入、标准输出、标准错误。每调用一次exec_command方法就相当于重新打开一次linux终端,终端环境都是新的。
print('shell')
stdin, stdout, stderr = ssh.exec_command('cd BRAYDEN20230213001xx;pwd',get_pty=True)
print('ls')
stdin, stdout, stderr = ssh.exec_command('cd BRAYDEN20230213001xx;ls',get_pty=True)
print(stdout.readlines())
print('execute')
stdin, stdout, stderr = ssh.exec_command('cd BRAYDEN20230213001xx;perl download.pl /',get_pty=True)
print(stdout.readlines())
print('pwd')
stdin, stdout, stderr = ssh.exec_command('pwd /')
print(stdout.readlines())
stdin, stdout, stderr = ssh.exec_command(order)
# 如果使用了sudo命令请启用下面的代码并填入对应的密码
# stdin.write("passwd")
# stdin.flush()
# 打印输出结果
print('pirnt-->1')
print(stdout.readlines())
# 打印命令执行错误信息
#print(stderr.readlines())
print('pirnt-->2')
if "allen" in stdout.readlines():
print('ssss')
else:
print('eeee')
for i in stdout:
print(stdout[i])
print('success to carry out command')
except:
print('Fail to carry out command')
ssh.close()
#遍历来源路径文集,上传文件
#获取各种文件的路径
def getPath(self,topName,objType):
try:
# 创建sshClient实例对象
ssh = paramiko.SSHClient()
# 设置信任远程机器,允许访问
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
except:
print("There is an error with the SSHClient")
try:
# 设置ssh远程连接机器,参数依次为地址、端口、用户名、密码,ssh端口默认22
print('server info :' , self.ip,self.port,self.userName,self.passWord)
ssh.connect(self.ip,#"10.10.11.110",
self.port,#
self.userName,#"appndev",
self.passWord#"appndev"
)
print("success to connect to remote server")
except:
print("Failed to connect to remote server")
'''
执行linux命令
'''
try:
# 设置代表需要执行的linux命令的变量,多条命令用分号隔开
order = "cd " + topName + ";pwd"
#order = "pwd"
# 每次执行命令会返回三个对象,对应标准输入、标准输出、标准错误。每调用一次exec_command方法就相当于重新打开一次linux终端,终端环境都是新的。
print('shell-->' + order)
stdin, stdout, stderr = ssh.exec_command('echo $AU_TOP',get_pty=True)
#stdin, stdout, stderr = ssh.exec_command('cd /data/ndev/apps/apps_st/appl/au/12.0.0;pwd')
# 如果使用了sudo命令请启用下面的代码并填入对应的密码
# stdin.write("passwd")
# stdin.flush()
# 打印输出结果
print('pirnt-->1')
print(stdout.readlines())
# 打印命令执行错误信息
#print(stderr.readlines())
print('pirnt-->2')
if "allen" in stdout.readlines():
print('ssss')
else:
print('eeee')
for i in stdout:
print(stdout[i])
print('success to carry out command')
except:
print('Fail to carry out command')
ssh.close()
if __name__ == '__main__':
#text_create()
ssh = PySSH('10.10.11.110',22,'用户','密码')
#ssh.putFtpDir('123','4565','dd')
#ssh.getPath('/data/ndev/apps/apps_st/appl/au/12.0.0/forms/ZHS','FORM')
ssh.getFtpfile()