模拟一个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执行命令的编解码说明的更多相关文章

  1. 远程ssh执行命令时提示找不到命令

    最开始的时候碰到这种问题,是在hadoop003上配置了jdk1.8, 在hadoop002上执行ssh hadoop003 java -version提示没有命令,先ssh hadoop003然后执 ...

  2. Linux远程ssh执行命令expect使用及几种方法

    expect命令实现脚本免交互 一.Linux下SSH无密码认证远程执行命令 在客户端使用ssh-keygen生成密钥对,然后把公钥复制到服务端(authorized_keys). 实现步骤: 1.客 ...

  3. python-ssh-远程服务器+远程docker执行命令

    在python语言中实现远程服务器执行命令+远程dcoker执行命令 def ssh_exec_command(ip, username, password, cmd=None): "&qu ...

  4. ssh 执行命令并实时显示结果

    ssh 执行命令并实时显示结果 import paramiko def main(): sshClient = paramiko.SSHClient() sshClient.set_missing_h ...

  5. C#登录SSH执行命令,下载文件

    前言 批量登录SSH执行命令 ,把应急响应中的日志文件下载回来. 代码实现 Renci.SshNet编译出DLL,引用. using System; using System.Collections. ...

  6. jenkins 执行ssh 远程linux执行命令

    1.远程机器编写脚本: 脚本名称为: /app/jboss/jboss-as/logs/ALL_SERVICE_STOP.sh 功能为:停止某个服务器某个目录下面的所有应用 #!/bin/bash p ...

  7. Python3学习之路~9.1 paramiko模块:实现ssh执行命令以及传输文件

    我们一般使用linux的时候,都是在Windows上安装一个ssh客户端连接上去.那么从一台linux如何连接到另一条linux呢?使用ssh命令即可,因为每台linux机器自己都有一个ssh客户端. ...

  8. python利用paramiko连接远程服务器执行命令

    python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件. 1.得到一个连接的对象 在进行连接的时候,可以使用如下的代码: d ...

  9. 批量ssh执行命令

    [root@openfire1 script]# cat test.sh  #!/bin/bash   #本地通过ssh执行远程服务器的脚本   for ip in `cat iplist`  do ...

随机推荐

  1. 【NOI2014】【BZOJ3669】【UOJ#3】魔法森林

    我学会lct辣 原题: 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为 1…n1…n,边标号为1…m1…m.初始时小E ...

  2. Js 向表单中添加多个元素

    @{ ViewBag.title = "地图导航"; } @model YT.XWAJ.Public.Application.MapNavigation.Dto.MapNaviga ...

  3. 利用JavaScript jQuery实现图片无限循环轮播(不借助于轮播插件)-----转载

    前言 作为一个前端工程师,无论公司是什么行业,无论你做什么端,基本都会遇到一个避不开的动画效果:循环轮播.做轮播并不难,市场上的轮播插件有很多,其中比较著名的是swiper,使用也非常简单.但轮播插件 ...

  4. malloc,calloc,alloca和free函数

    void *malloc(size_t size)因为返回类型为空,所以可以赋值到任何类型指针,其分配的空间大小为size,返回新分配内存地址的起始处的指针,其所分配的内存未经初始化,若分配失败返回N ...

  5. readv与writev

    [root@bogon mycode]# cat writev.c #include<stdio.h> #include<string.h> #include<unist ...

  6. 续drone 1.0 新界面调整

    接以前的内容,drone 最新发布的版本又有界面信息的调整了,更方便了. 环境准备 docker-compose 文件 version: '3' services: drone-server: ima ...

  7. Chrome——F12 谷歌开发者工具详解

    我们这里介绍主要的几块:Console.Source.Network Console 大家都有用过各种类型的浏览器,每种浏览器都有自己的特色,本人拙见,在我用过的浏览器当中,我是最喜欢Chrome的, ...

  8. ThinkPHP3 和 ThinkPHP5 不是一个团队做的

    ThinkPHP3 和 ThinkPHP5 不是一个团队做的 发现流年好幽默. 这个帖子源于一个 ThinkPHP 用户被客户投诉,然后反过来骂 ThinkPHP 垃圾. 不过最后想通了道歉. 开源需 ...

  9. 为什么js 的constructor中是无限循环嵌套:Foo.__proto__.constructor.prototype.constructor.prototype.constructor.prototype.xxx ?

    constructor始终指向创建当前对象实例的(构造)函数. 任何函数都是Function类的一个实例 那么根据上述可知:任何函数的constructor属性都指向Function类,而Functi ...

  10. Jenkins 配置用户权限错误导致无法登录解决方案

    最初配置Jenkins的用户管理权限时,因为不熟悉很容易将用户角色配置错误,导致配置用户后无法登录系统: 登录系统时候提示"Access Denied": 解决办法: 进入Jenk ...