Paramiko之远程执行命令
简单介绍
paramiko最开始是用Python对ssh进行的一个封装,封装就是对一些面向对象的方法,就是把变量和方法给他包装起来。提供一些外部的api,给大家很方便的使用它。
paramiko详解介绍可查看官网信息 http://docs.paramiko.org/en/2.4/index.htm
安装
# window系统下 安装命令
pip install paramiko
远程执行命令关键点
远程执行命令主要利用了paramiko的class paramiko.client.SSHClient
类,这个类介绍如下:
A high-level representation of a session with an SSH server. This class wraps Transport, Channel, and SFTPClient to take care of most aspects of authenticating and opening channels。
其典型用法如下:
client = SSHClient()
client.load_system_host_keys()
# 链接服务器
client.connect(hostname, port=22, username=None, password=None)
# 返回元组类型
stdin, stdout, stderr = client.exec_command('ls -l')
需要注意的是每次执行exec_command()
命令都会重写打开一个channel,初始连接到服务器其初始路径一般是/root
.
如果我们想要执行多条的命令,我们需要在同个channel中进行才可以,每个命令使用‘;’作为分隔符,否则命令执行和预期不同。
例如:
def run_cmd(client, cmd):
# 命令执行
stdin, stdout, stderr = client.exec_command(cmd)
cmd_result = stdout.read(), stderr.read()
for line in cmd_result:
print(line)
if __name__ == "__main__":
ip = '103.xxx.xxx.xx'
usr = 'root'
password = 'xxx'
#paramiko 远程执行命令封装,后面给出完整内容
client = ssh_client(ip, usr, password)
# 不同channel中进行
run_cmd(client, 'cd jimmy') # cmd 1
run_cmd(client, 'ls')# cmd 2
# 执行多条命令,同个channel中进行
run_cmd(client, 'cd jimmy;ls') # cmd 3
client.close()
执行效果:
''
'91yunserverspeeder\n91yunserverspeeder.tar.gz\nanaconda-ks.cfg\njimmy\nnohup.out\noriginal-ks.cfg\nserverspeeder.sh\nshadowsocks.log\nshadowsocks.sh\ntest\ntest.c\ntest.zip\n'
"
'github\ntest.log\n'
''
结果验证:
我们发现仅cmd3命令达到了我们的预期,进入jimmy目录,并列出目录下的文件
命令封装
为了方便使用封装了一个CCmd类,可同时支持一个命令和多个命令执行,其代码如下:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import paramiko
import sys
class CCmd(object):
"""
远程执行命令类
"""
def __init__(self, cmd_client):
self.cmd_client = cmd_client
self.cmd_list = ''
self.cmd_result = ''
def __exec_cmd(self, user_cmd):
"""
A new Channel is opened and the requested command is executed.
:param user_cmd:
:return:
"""
print('user input cmd:{}'.format(user_cmd))
try:
stdin, stdout, stderr = self.cmd_client.exec_command(user_cmd)
self.cmd_result = stdout.read()
except paramiko.SSHException:
print('run cmd error')
sys.exit(1)
def get_cmd_result(self):
"""
返回命令执行结果
:return:
"""
return 'exec cmd result:{}'.format(self.cmd_result)
def run_cmd(self, __cmd):
"""
执行命令
"""
if len(__cmd):
self.__exec_cmd(__cmd)
else:
print('cmd is empty')
sys.exit(1)
def add_cmd(self, cmd_cell):
"""
添加命令
:param cmd_cell:
:return:
"""
self.cmd_list += cmd_cell
# 多条命令分隔符
self.cmd_list += ';'
def run_multi_cmd(self):
"""
同时执行多个命令
:return:
"""
# 不要最后一个分隔符;
cmd_list = self.cmd_list[:-1]
if len(cmd_list):
self.run_cmd(cmd_list)
else:
print('cmd is empty')
sys.exit(1)
if __name__ == "__main__":
pass
CCmd命令使用
try:
client = ssh_client(ip, usr, password)
cmd = CCmd(client)
# case 1
cmd.add_cmd('cd jimmy')
cmd.add_cmd('ls')
cmd.run_multi_cmd()
print(cmd.get_cmd_result())
# case 2
cmd.run_cmd('pwd')
print(cmd.get_cmd_result())
client.close()
except Exception:
sys.exit(1)