python3执行linux命令-python3 远程Linux服务器执行命令和上传下载文件

一、简介

paramiko是一个基于SSH用于连接远程服务器并执行相关操作(SSHClient和SFTPClinet,即一个是远程连接,一个是上传下载服务),使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。

二、使用

1、下载

pip3 install paramiko

2、模块使用

SSHClient:

远程连接分为两种:(1)基于用户名密码连接 (2)基于公钥秘钥连接

通过是用paramiko远程操作,其实本质也分为两种:(1)只用SSHClient (2)自己创建一个transport

(1)基于用户名和密码的连接

importparamiko#创建SSH对象

ssh =paramiko.SSHClient()#允许连接不在know_hosts文件中的主机

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#连接服务器

ssh.connect(hostname="c1.salt.com", port=22, username="GSuser", password="123")#执行命令

stdin, stdout, stderr = ssh.exec_command("ls")#获取命令结果

result =stdout.read()#关闭连接

ssh.close()

SSHClient 封装 Transport

importparamiko

transport= paramiko.Transport(("hostname", 22))

transport.connect(username="GSuser", password="123")

ssh=paramiko.SSHClient()

ssh._transport=transport

stdin, stdout, stderr= ssh.exec_command("df")print(stdout.read())

transport.close()

(2)基于公钥秘钥连接

importparamiko#添加公钥密钥文件

private_key = paramiko.RSAKey.from_private_key_file("/home/auto/.ssh/id_rsa")#创建SSH对象

ssh =paramiko.SSHClient()#允许连接不在know_hosts文件中的主机

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#连接服务器

ssh.connect(hostname="192.168.1.105", port=22, username="666", key=private_key)#执行命令#执行多条命令时需要将各个命令用";’隔开,最后将get_pty设为True;如果是单条命令的则只传入命令即可

stdin, stdout, stderr = ssh.exec_command("cd dw/2020-06-02/;ls",get_pty=True)#多条命令的话会将执行结果一起返回,所以建议遍历打印。也可以直接打印:print(stdout.read().decode("utf-8"))

files =stdout.readlines()for i infiles:#打印执行反馈结果

print(i.encode().decode("utf-8").split()[0])#打印报错信息

print(stderr.read().decode("utf-8"))#关闭连接

ssh.close()

SSHClient 封装Transport

importparamiko

private_key= paramiko.RSAKey.from_private_key_file("/home/auto/.ssh/id_rsa")

transport= paramiko.Transport(("192.168.1.105", 22))

transport.connect(username="666", pkey=private_key)

ssh=paramiko.SSHClient()

ssh._transport=transport#执行多条命令时需要将各个命令用";’隔开,最后将get_pty设为True;如果是单条命令的则只传入命令即可

stdin, stdout, stderr = ssh.exec_command("cd dw/2020-06-02/;ls",get_pty=True)#多条命令的话会将执行结果一起返回,所以建议遍历打印。也可以直接打印:print(stdout.read().decode("utf-8"))

files =stdout.readlines()for i infiles:#打印执行反馈结果

print(i.encode().decode("utf-8").split()[0])#打印报错信息

print(stderr.read().decode("utf-8"))

transport.close()

SFTPClient:

用于连接远程服务器并进行上传下载功能。

(1)基于用户名密码上传下载

importparamiko

transport= paramiko.Transport(("192.168.1.105",22))

transport.connect(username="666",password="123")

sftp=paramiko.SFTPClient.from_transport(transport)#将location.py 上传至服务器 /tmp/test.py

sftp.put("/tmp/location.py", "/tmp/test.py")#将remove_path 下载到本地 local_path

sftp.get("remove_path", "local_path")

transport.close()

(2)基于公钥秘钥上传下载

importparamiko

private_key= paramiko.RSAKey.from_private_key_file("/home/auto/.ssh/id_rsa")

transport= paramiko.Transport(("192.168.1.105", 22))

transport.connect(username="666", pkey=private_key )

sftp=paramiko.SFTPClient.from_transport(transport)#将location.py 上传至服务器 /tmp/test.py

sftp.put("/tmp/location.py", "/tmp/test.py")#将remove_path 下载到本地 local_path

sftp.get("remove_path", "local_path")

transport.close()

Demo: 实现远程命令执行和文件上传

#!/usr/bin/env python#-*- coding:utf-8 -*-

importparamikoclassSSHConnection(object):def __init__(self, host="192.168.12.68", port=22, username="locojoy",pwd="123321QQ!"):

self.host=host

self.port=port

self.username=username

self.pwd=pwd

self.__k =Nonedefrun(self):

self.connect()#连接远程服务器

self.upload("db.py","/tmp/1.py") #将本地的db.py文件上传到远端服务器的/tmp/目录下并改名为1.py

self.cmd("df") #执行df 命令

self.close() #关闭连接

defconnect(self):

transport=paramiko.Transport((self.host, self.port))

transport.connect(username=self.username, password=self.pwd)

self.__transport =transportdefclose(self):

self.__transport.close()defupload(self,local_path,target_path):

sftp= paramiko.SFTPClient.from_transport(self.__transport)

sftp.put(local_path,target_path)defcmd(self, command):

ssh=paramiko.SSHClient()

ssh._transport= self.__transport

#执行命令

stdin, stdout, stderr =ssh.exec_command(command)#获取命令结果

result =stdout.read()print(result)returnresult

obj=SSHConnection()

obj.run()

paramiko在堡垒机中的应用

(1)简单实例:远程连接一台主机,操作命令,linux版本,输入终端为回车则发送命令。不支持tab补全功能。

importparamiko, sys, os, socket, select, getpassfrom paramiko.py3compat import u #在python3中是这样使用的,如果在Python2中则注释这行

#这个程序依赖于终端,只能在Liunx下运行,windows用其他的方式

tran= paramiko.Transport(("192.168.12.68", 22,))

tran.start_client()

tran.auth_password("locojoy", "123321QQ!")#打开一个通道

chan =tran.open_session()#获取一个终端

chan.get_pty()#激活器

chan.invoke_shell()#原始的方法利用终端进行收发消息#利用sys.stdin,肆意妄为执行操作#用户在终端输入内容,并将内容发送至远程服务器#远程服务器执行命令,并将结果返回#用户终端显示内容

whileTrue:#监视用户输入和服务器返回数据

#sys.stdin 处理用户输入

#chan 是之前创建的通道,用于接收服务器返回信息

#通过select监听终端(输入输出),一旦变化,就将拿到的数据发送给服务器

#通过监听socket句柄,如果有变化表示服务器要给我发消息

readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)#通过select.select 监听chan(打开的通道(和远程服务器连接的状态)), sys.stdin(输入),一旦变化就写入readable

#当chan变化时,加入到readable,远程服务器发送内容过来

if chan inreadable:try:

x= u(chan.recv(1024)) #Python3用这个

#x = chan.recv(1024) Python2使用这个

if len(x) ==0:print(" *** EOF ")breaksys.stdout.write(x)#写入缓冲区

sys.stdout.flush() #刷新,将缓冲区内容显示出来

exceptsocket.timeout:pass

#当sys.stdin 放入readable中时,将获取到的内容发送到远程服务器

if sys.stdin inreadable:

inp=sys.stdin.readline()

chan.sendall(inp)

chan.close()

tran.close()

(2)每按一个键就发送记录,并支持tab自动补全

importparamiko, sys, os, socket, select, getpass, termios, ttyfrom paramiko.py3compat importu

tran= paramiko.Transport(("10.211.55.4", 22,))

tran.start_client()

tran.auth_password("wupeiqi", "123")#打开一个通道

chan =tran.open_session()#获取一个终端

chan.get_pty()#激活器

chan.invoke_shell()#获取原tty属性

oldtty =termios.tcgetattr(sys.stdin)try:#为tty设置新属性

#默认当前tty设备属性:

#输入一行回车,执行

#CTRL+C 进程退出,遇到特殊字符,特殊处理。

#这是为原始模式,不认识所有特殊符号

#放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器

tty.setraw(sys.stdin.fileno()) #恢复终端原始状态,每按一个键就发送

chan.settimeout(0.0)whileTrue:#监视 用户输入 和 远程服务器返回数据(socket)

#阻塞,直到句柄可读

r, w, e = select.select([chan, sys.stdin], [], [], 1)if chan in r: #获取服务返回的内容

try:

x= u(chan.recv(1024))if len(x) ==0:print(" *** EOF ")breaksys.stdout.write(x)

sys.stdout.flush()exceptsocket.timeout:pass

if sys.stdin in r: #发送命令

x = sys.stdin.read(1) #读取一个字符

if len(x) ==0:breakchan.send(x)#发送一个字符

finally:#重新设置终端属性,将终端状态还原

termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

chan.close()

tran.close()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值