在日常工作中,少不了需要上服务器执行一些操作或者命令,即使在现在云时代,但是一旦出现问题,还是需要上机排查,所以写了一个小小的跳板机工具
在写这个小工具之前,我就在想一定要非常简单,足够简单,所以这里用了不到 200 行代码,写了一个,可以说是非常简单。
1. 使用模块介绍
- pexpect
就这一个就完了!
简单介绍一下这个模块:
pexpect 是 expect 的一个 python 实现,用来进行人机交互,比如执行某一段程序时要求输入用户名和密码,或者是 yes/no 这种情况时,使用 pexpect 便可以通过捕获这种关键字进行输入一些必要信息来继续操作程序。
pexpect 的使用范围很广,可以用来实现与 ssh、ftp 、telnet 等程序的自动交互
1.1 使用方式
pexpect 的使用基本上分为三个步骤:
- 首先用 spawn 来执行一条命令或者一段程序
- 然后 expect 捕获关键字
- 捕获到指定关键字后,执行 send 指令发送必要的内容来继续操作程序
1.1.1 spawn
类
spawn
是 pexpect 的一个主要类,用来执行一个程序,并返回一个操作这个程序的句柄,后面的一系列操作都可以通过这个句柄来完成,下面是它的构造函数的定义:
class spawn(command, args=[], timeout=30, maxread=2000,
searchwindowsize=None, logfile=None, cwd=None,env=None,
ignore_sighup=False, echo=True, preexec_fn=None,
encoding=None, codec_errors='strict', dimensions=None,
use_poll=False)
command
是任意的命令
child = pexpect.spawn('/usr/bin/ftp')
child = pexpect.spawn('/usr/bin/ssh user@example.com')
child = pexpect.spawn('ls -latr /tmp')
但是当包含一些特殊字符时(>, |, or *),就必须启动一个 shell 来执行了,例如:
child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"')
child.expect(pexpect.EOF)
也可以这样写,定一个变量,将要执行的命令通过这个变量来接收
shell_cmd = 'ls -l | grep LOG > logs.txt'
child = pexpect.spawn('/bin/bash', ['-c', shell_cmd])
child.expect(pexpect.EOF)
args=[]
执行程序时传入所需的参数
child = pexpect.spawn('/usr/bin/ftp', [])
child = pexpect.spawn('/usr/bin/ssh', ['user@example.com'])
child = pexpect.spawn('ls', ['-latr', '/tmp'])
-
timeout=30
设置超时时间 -
maxread=2000
pexpect 从终端控制台一次读取的最大字节数 -
searchwindowsize
匹配缓冲区字符串的位置,默认是从开始位置匹配
不过有时候需要打印下执行的结果,也就是将输出打印到标准输出里,方式如下:
import pexpect
import sys
child = pexpect.spawn("df -h", encoding='utf-8')
child.logfile = sys.stdout
child.expect(pexpect.EOF)
必须要加上encoding='utf-8'
,否则会报TypeError: write() argument must be str, not bytes
当然,也可以使用logfile
这个参数,例如:
child = pexpect.spawn("df -h", logfile=sys.stdout, encoding='utf-8')
child.expect(pexpect.EOF)
1.1.2 expect
方法
expect
最后会返回 0 表示匹配到了所需的关键字,如果定义了一个关键字列表的话,就会返回一个数字表示匹配到了列表中第几个关键字,从 0 开始计算,也就是该关键字所在的索引号
expect(pattern, timeout=-1, searchwindowsize=-1, async_=False<