一 、安装
1.1、win10系统
安装最新版本pip3后,使用pip3 install paramiko命令
E:\>pip3 install paramiko Collecting paramiko Downloading paramiko-2.8.0-py2.py3-none-any.whl (206 kB) |████████████████████████████████| 206 kB 24 kB/s Collecting cryptography>=2.5 Downloading cryptography-36.0.0-cp36-abi3-win_amd64.whl (2.2 MB) |████████████████████████████████| 2.2 MB 38 kB/s Collecting pynacl>=1.0.1 Downloading PyNaCl-1.4.0-cp35-abi3-win_amd64.whl (206 kB) |████████████████████████████████| 206 kB 16 kB/s Collecting bcrypt>=3.1.3 Downloading bcrypt-3.2.0-cp36-abi3-win_amd64.whl (28 kB) Requirement already satisfied: cffi>=1.12 in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from cryptography>=2.5->paramiko) (1.14.5) Requirement already satisfied: six in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from pynacl>=1.0.1->paramiko) (1.15.0) Requirement already satisfied: pycparser in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from cffi>=1.12->cryptography>=2.5->paramiko) (2.20) Installing collected packages: cryptography, pynacl, bcrypt, paramiko Successfully installed bcrypt-3.2.0 cryptography-36.0.0 paramiko-2.8.0 pynacl-1.4.0
1.2、centos系统
yum install python-paramiko
二、使用
参考链接:https://blog.csdn.net/liulanba/article/details/114596709
paramiko是用python语言写的一个模块,远程连接到Linux服务器,查看上面的日志状态,批量配置远程服务器,文件上传,文件下载等,提供了ssh及sftp进行远程登录服务器执行命令和上传下载文件的功能。
2.1、基于用户名和密码实现SSH功能
import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在known_hosts文件上的主机 # 即允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname="192.168.0.99", port=22, username="root", password="rootroot") # 执行命令 stdin, stdout, stderr = ssh.exec_command('df') # 结果放到stdout中,如果有错误将放到stderr中 result = stdout.read().decode() # 获取错误提示(stdout、stderr只会输出其中一个) err = stderr.read() # 关闭连接 ssh.close() print(stdin, result, err)
2.2、基于用户名和密码的 transport 方式登录
前一种方式是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,上面方法则无法实现,可以通过如下方式来操作。
#SSHClient 封装 Transport import paramiko # 实例化一个transport对象 transport = paramiko.Transport(('192.168.199.146', 22)) # 建立连接 transport.connect(username='fishman', password='9') # 将sshclient的对象的transport指定为以上的transport ssh = paramiko.SSHClient() ssh._transport = transport # 执行命令,和传统方法一样 stdin, stdout, stderr = ssh.exec_command('df') print (stdout.read().decode()) # 关闭连接 transport.close()
2.3、基于用户名和密码实现SFTP功能
import paramiko # 连接虚拟机centos上的ip及端口,实例化一个transport对象 transport = paramiko.Transport(("192.168.0.99", 22)) transport.connect(username="root", password="rootroot") # 将实例化的Transport作为参数传入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 将“calculator.py”上传到filelist文件夹中 sftp.put('D:\python库\Python_shell\day05\calculator.py', '/filelist/calculator.py') # 将centos中的aaa.txt文件下载到桌面 sftp.get('/filedir/aaa.txt', r'C:\Users\duany_000\Desktop\test_aaa.txt') transport.close()
2.4、使用秘钥实现SSH功能
import paramiko private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 创建SSH对象 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='192.168.79.9', port=22, username='root', pkey=private_key) stdin, stdout, stderr = ssh.exec_command('ifconfig') res_out = stdout.read() print(res_out.decode()) ssh.close()
2.5、基于密钥的 Transport 方式登录
# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数 pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345') # 建立连接 trans = paramiko.Transport(('192.168.2.129', 22)) trans.connect(username='super', pkey=pkey) # 将sshclient的对象的transport指定为以上的trans ssh = paramiko.SSHClient() ssh._transport = trans # 执行命令,和传统方法一样 stdin, stdout, stderr = ssh.exec_command('df -hl') print(stdout.read().decode()) # 关闭连接 trans.close()
2.6、使用秘钥实现SFTP功能
import paramiko private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 连接虚拟机centos上的ip及端口 transport = paramiko.Transport(("192.168.79.9", 22)) transport.connect(username="root", pkey=private_key) # 将实例化的Transport作为参数传入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 将“calculator.py”上传到filelist文件夹中 sftp.put('D:\python库\Python_shell\day05\calculator.py', '/filedir/calculator.py') # 将centos中的aaa.txt文件下载到桌面 sftp.get('/filedir/oldtext.txt', r'C:\Users\duany_000\Desktop\oldtext.txt') transport.close()
2.7、实现输入命令立马返回结果的功能
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()
2.8、支持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()
2.9、exec_command()函数
官方解释为
def exec_command( self, command, bufsize=-1, timeout=None, get_pty=False, environment=None, ): """ 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. :param str command: the command to execute :param int bufsize: interpreted the same way as by the built-in ``file()`` function in Python :param int timeout: set command's channel timeout. See `.Channel.settimeout` :param bool get_pty: Request a pseudo-terminal from the server (default ``False``). See `.Channel.get_pty` :param dict environment: a dict of shell environment variables, to be merged into the default environment that the remote command executes within. .. warning:: Servers may silently reject some environment variables; see the warning in `.Channel.set_environment_variable` for details. :return: the stdin, stdout, and stderr of the executing command, as a 3-tuple :raises: `.SSHException` -- if the server fails to execute the command .. versionchanged:: 1.10 Added the ``get_pty`` kwarg. """ chan = self._transport.open_session(timeout=timeout) if get_pty: chan.get_pty() chan.settimeout(timeout) if environment: chan.update_environment(environment) chan.exec_command(command) stdin = chan.makefile_stdin("wb", bufsize) stdout = chan.makefile("r", bufsize) stderr = chan.makefile_stderr("r", bufsize) return stdin, stdout, stderr
用法:
ssh.exec_command('cd /home/nvidia/lf && python test.py') print(stdout.read())
这种在命令完成后才显示信息!但是,执行文件时,如果又不断输出,希望输出一条打印一条,而不是在以后输出,修改为:
# 执行命令 stdin, stdout, stderr = ssh.exec_command('cd /home/nvidia/lf && python test.py') for line in iter(stdout.readline, ""): print(line, end="") print('finished.')
import paramikoimport osimport selectimport sysimport ttyimport termios
'''实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果支持自动补全,直接调用服务器终端
'''# 建立一个sockettrans = 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()————————————————版权声明:本文为CSDN博主「liulanba」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/liulanba/article/details/114596709