模拟远程SSH执行命令的编解码说明
模拟一个SSH“远程”执行命令并获取命令结果的一个程序:
1、在C/S架构下,当客户端与服务器建立连接(这里以TCP为例)后,二者可以不断的进行数据交互。SSH远程可以实现的效果是客户端输入命令可以在服务器中执行并且可以将结果返回给客户端。但是需要注意的一点事:客户端的“命令”在计算机看来仅仅是“字符串”而已,而真正需要执行的“命令”必须是操作系统能够识别的!也就是说,真正“执行命令”与“返回结果”的地方仍然是服务器端。在客户端我们只是“显示”出了一个这样的知执行假象而已。
那么,这样的一个SSH远程执行程序的具体流程是怎样的呢?
下图是这样的一个简单过程:

简单的过程说明:
对于客户端来讲,用户首先输入了str类型的命令command,然后程序将这个str类型的字符串encode成能够在网络中传输的bytes类型的数据并发送给服务器;服务器接收到以后将其重新解码为str,然后在本段“执行”这段代码生成str类型的结果,接着再进行编码传给客户端,客户端接收到以后解码为人能识别的str类型最终输出到屏幕上。
2、这个过程有两个大问题:一个是服务器端是如何进行“代码执行”的,另一个就是客户端与服务器端str与bytes格式数据的编解码问题。
2.1、对于第一个问题,我们利用subprocess模块下的Popen方法可以将str类型的“虚假命令”转换为操作系统能够识别的“真是命令”:
import subprocess
cmd = input('>>>:')
obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
print(obj.stdout.read().decode('gbk'))
print(obj.stderr.read().decode('gbk'))
这里有几点需要说明:
(1)可以把obj看成是一个管道,它一次性的、毫无保留将所有执行结果都拿到,再一次取值时里面没有了数据,这就像一个“管道”一样,里面的数据全部取完后就“无所保留”了。

(2)关于输出结果解码的问题:subprocess模块下的Popen方法在不同的操作系统下结果的编码方式不同:linux下为utf-8模式,windows下为gbk模式。由于本例是在windows操作系统下进行的,所以我们在输出是要进行gbk的方式解码才能看到结果。
(3)最终的结果包含正确的信息stdout与错误的结果stderr(当用户输入一个不存在的命令时产生)。
2.2、第二个编解码问题可以看下图具体的描述:

这里需要注意的一点是:本例是在windows操作系统下执行的,所以result的编码方式要以gbk模式进行,这样才不会在客户端中产生乱码。
程序的代码以及运行结果为:
import socket
import subprocess server_whw = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_whw.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server_whw.bind(('127.0.0.1',8008))
server_whw.listen(5)
print('Starting......')
conn,client_addr = server_whw.accept() while 1:
try:
cmd = conn.recv(8096)
#将从客户端传来的命令信息进行处理
obj = subprocess.Popen(cmd.decode('utf-8'),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#将结果返回给客户端
stdout = obj.stdout.read().decode('gbk')
stderr = obj.stderr.read().decode('gbk') std1 = stdout.encode('gbk')
std2 = stderr.encode('gbk')
conn.send(std1)
conn.send(std2) except ConnectionResetError:
print('连接断开')
break
conn.close()
server_whw.close()
Server_ssh
import socket client_whw = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_whw.connect(('127.0.0.1',8008))
while 1:
cmd = input('请输入命令:')
if not cmd:
continue
client_whw.send(cmd.encode('utf-8'))
data = client_whw.recv(1024)
print('命令结果:\n',data.decode('gbk'))
# client_whw.close()
Client_ssh
程序演示:

当然,最终的结果出现了粘包问题~需要进行进一步的处理
模拟远程SSH执行命令的编解码说明的更多相关文章
- 远程ssh执行命令时提示找不到命令
最开始的时候碰到这种问题,是在hadoop003上配置了jdk1.8, 在hadoop002上执行ssh hadoop003 java -version提示没有命令,先ssh hadoop003然后执 ...
- Linux远程ssh执行命令expect使用及几种方法
expect命令实现脚本免交互 一.Linux下SSH无密码认证远程执行命令 在客户端使用ssh-keygen生成密钥对,然后把公钥复制到服务端(authorized_keys). 实现步骤: 1.客 ...
- python-ssh-远程服务器+远程docker执行命令
在python语言中实现远程服务器执行命令+远程dcoker执行命令 def ssh_exec_command(ip, username, password, cmd=None): "&qu ...
- ssh 执行命令并实时显示结果
ssh 执行命令并实时显示结果 import paramiko def main(): sshClient = paramiko.SSHClient() sshClient.set_missing_h ...
- C#登录SSH执行命令,下载文件
前言 批量登录SSH执行命令 ,把应急响应中的日志文件下载回来. 代码实现 Renci.SshNet编译出DLL,引用. using System; using System.Collections. ...
- jenkins 执行ssh 远程linux执行命令
1.远程机器编写脚本: 脚本名称为: /app/jboss/jboss-as/logs/ALL_SERVICE_STOP.sh 功能为:停止某个服务器某个目录下面的所有应用 #!/bin/bash p ...
- Python3学习之路~9.1 paramiko模块:实现ssh执行命令以及传输文件
我们一般使用linux的时候,都是在Windows上安装一个ssh客户端连接上去.那么从一台linux如何连接到另一条linux呢?使用ssh命令即可,因为每台linux机器自己都有一个ssh客户端. ...
- python利用paramiko连接远程服务器执行命令
python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件. 1.得到一个连接的对象 在进行连接的时候,可以使用如下的代码: d ...
- 批量ssh执行命令
[root@openfire1 script]# cat test.sh #!/bin/bash #本地通过ssh执行远程服务器的脚本 for ip in `cat iplist` do ...
随机推荐
- python3 sort
#https://docs.python.org/3.5/howto/sorting.html?highlight=sort #In Python 3.2, the functools.cmp_to_ ...
- LeetCode - Max Area of Island
Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...
- 【maven】maven查看项目依赖并解决依赖冲突的问题
一.问题 项目开发过程中,经常会遇到jar冲突,然后maven根据自己的规则进行冲突解决,导致项目在运行的过程中报错. 1.maven自动解决依赖冲突的规则是什么? 2.如何查看当前项目的maven的 ...
- PureComponent的作用及一些使用陷阱
默认渲染行为的问题 在React Component的生命周期中,有一个shouldComponentUpdate方法.这个方法默认返回值是true. 这意味着就算没有改变组件的props或者stat ...
- Windows和linux 文件互传
一般我是直接在windows下创建一个共享文件夹,然后在linux挂载,我一直都是这么干的. 直到有一天,我需要往一个公网linux上面传几个文件,可是我的Windows是内网的,所以,这种方法行不通 ...
- linux服务器的日志管理
消息紧急程度排行 emerg:该系统不可用 alert:需要立即修改 crit:紧急情况 err:错误信息 warning:预警信息 notice:具有重要性的普通条件 info:提供信息的消息 de ...
- jsonDB使用手冊
已在github上建立项目:https://github.com/ThinkerCodeChina/jsonDB 博客:http://blog.csdn.net/thinkercode/ 简单介绍: ...
- NET使用NPOI组件导出Excel-入门示例及通用方法
一.Excel导入及导出问题产生: 从接触.net到现在一直在维护一个DataTable导出到Excel的类,时不时还会维护一个导入类.以下是时不时就会出现的问题: 导出问题: 如果是as ...
- oracle-pl/sql之一
http://www.cnblogs.com/huyong/archive/2011/05/10/2041951.html#_Toc15837 SQL语言只是访问.操作数据库的语言,并不是一种具有流程 ...
- MySQL聚合函数与数据分组
我们最常需要的是汇总数据而不是把他们实际检索出来 确定表中行数(或满足某个条件或包含某个特定值的行数) 确定表中行组的和 找出表列(或所有行或特定列)的最大值,最小值和平均值 聚集函数是运行在行组上, ...