zoukankan      html  css  js  c++  java
  • pexpect获取远端命令执行结果

      

    类比于shell的expect, python中使用pexpect模块来模拟用户和终端交互。有的时候使用pexpect.sendline发送命令后,在各种条件影响下, 可能并不能保证命令在远端服务器执行成功(例如sftp下执行远端rename/rm,实际文件可能并未成功改名/删除)。这个时候就可能需要获取命令执行结果,然后分析结果来对命令的执行状态进行最终确认!

    pexpect模块中可以通过pexpect.before/pexpect.buffer获取命令执行结果:

    pexpect.buffer   -- 动态保存每一次expect后的所有内容. before/after都依赖此内容;
    pexpect.before   -- 匹配到的关键字之外的字符;expect后会设置before/after, 具体参考附录,摘录一段文字如下:

    There are two important methods in Pexpect – expect() and send() (or sendline() which is like send() with a linefeed). The expect() method waits for the child application to return a given string. The string you specify is a regular expression, so you can match complicated patterns. The send() method writes a string to the child application. From the child’s point of view it looks just like someone typed the text from a terminal. After each call to expect() the before and after properties will be set to the text printed by child application. The before property will contain all text up to the expected string pattern. The after string will contain the text that was matched by the expected pattern. The match property is set to the re match object.

    测试 -- 模拟sftp登陆后然后执行ls命令查看远端路径

    linux:~ # tree /root/sftp/
    /root/sftp/
    ├── csv
    │   ├── 1000.csv
    │   └── 3000.csv
    └── dat
        ├── 1000.dat
        └── 3000.dat
    
    2 directories, 4 files
    linux:~ #
    linux:~ # cat pexpect_test.py
    import os
    import sys
    import pexpect
    
    def pexpect_get_command_result(command, process, prompt = 'sftp>'):
      process.sendline('')             # 发送空行, 初始环境
      process.expect(prompt)       
      process.buffer = ""              # 清空buffer, 防止互相影响
      process.sendline(command)
      process.expect(prompt)           # expect后得到的expect.before就是命令和执行结果
    
      return process.before.strip()    # 返回结果
    
    def pexpect_connect():
      process = pexpect.spawn('sftp 127.0.0.1', timeout=30)
      index = process.expect(["assword: ", "yes/no", pexpect.EOF, pexpect.TIMEOUT])
    
      if index not in [0, 1]:
        print "[-] sftp login failed, due to TIMEOUT or EOF"
        return None
    
      if 1 == index:
        process.sendline("yes")
        process.expect("assword: ")
    
      process.sendline('passwd')
    
      return process
    
    if __name__ == '__main__':
      process = pexpect_connect()
      if process == None:
        sys.exit(-1)
    
      allpath = ['/root/sftp/dat', '/root/sftp/csv']
      for path in allpath:
        print pexpect_get_command_result('ls ' + path, process)
    
      process.sendline("bye")
    
      process.close(force = True)
    linux:~ #
    linux:~ # python pexpect_test.py
    ls /root/sftp/dat
    /root/sftp/dat/1000.dat   /root/sftp/dat/3000.dat
    ls /root/sftp/csv
    /root/sftp/csv/1000.csv   /root/sftp/csv/3000.csv
    linux:~ #

    参考

    https://pexpect.readthedocs.io/en/stable/
    http://www.noah.org/python/pexpect/
    https://www.cnblogs.com/zz27zz/p/7918717.html
    
    引用出处:
    https://pexpect.readthedocs.io/en/stable/overview.html?highlight=pexpect.buffer

    Excellence, is not an act, but a habit.
    作者:子厚.
    出处:http://www.cnblogs.com/aios/
    本文版权归作者和博客园共有,欢迎转载、交流、点赞、评论,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 相关阅读:
    Android Volley入门到精通:定制自己的Request
    Android高效加载大图、多图解决方案,有效避免程序OOM
    Android Volley入门到精通:使用Volley加载网络图片
    Android Volley入门到精通:初识Volley的基本用法
    彻底理解ThreadLocal
    Android中Parcelable接口用法
    Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息,handler详解
    Storm流处理项目案例
    021 使用join()将数组转变为字符串
    020 $.each的使用
  • 原文地址:https://www.cnblogs.com/aios/p/10288512.html
Copyright © 2011-2022 走看看