当前位置: 首页 > 工具软件 > Pexpect > 使用案例 >

pexpect

秦景同
2023-12-01

pexpect

spawn类

功能

  • 启动和控制子应用程序

构造函数

-

class pexpect.spawn(command,args=[],timeout=30,maxread=2000,searchwindowsize=None,logfile=None,cwd=None,env=None,ignore_sighup=True)
  • command:可以是任意已知的系统命令
  • args:当子程序需要参数时,可以使用python列表来代替参数
  • timeout:等待结果的超时时间
  • maxread:是pexpect从终端控制台一次读取的最大字节数
  • searchwindowsize:为匹配缓冲区字符串的位置(默认从头开始位置匹配)
  • 注意:pexpect不会解析shell命令中的元字符('>','|','*')

-

child=pexpect.spawn('/bin/bash -c "ls -l|grep shell>shell.txt"')
child.expect(pexpect.EOF)

-

shell_cmd='ls -l |grep shell>shell.txt'
child=pexpect.spawn('/bin/bash',['-c',shell_cmd])
child.expect(pexpect.EOF)

获取pexpect的输入和输出

日志文件

-

child=pexpect('commands')
fout=file('log.txt','w')
child.logfile=fout

输出到标准输出

-

child=pexpect.spawn('commands')
child.logfile=sys.stdout

实例ssh

-

[root@server6 ~]# python ssh.py 
Traceback (most recent call last):
  File "ssh.py", line 2, in <module>
    import pexpect
  File "/root/pexpect.py", line 3, in <module>
AttributeError: 'module' object has no attribute 'spawn'
[root@server6 ~]# ls
anaconda-ks.cfg  index.html            other.py             psutil-2.0.0
A.py             initial-setup-ks.cfg  passwd               shell
CNAME.py         localhost.53420:      pexpecet-3.0.tar.gz  shell.bak
cpu.py           mem.py                pexpect-3.0          sh.py
demo1.py         MX.py                 pexpect.pyc          ssh
Desktop          net.py                popen.py             ssh.py
disk.py          NS.py                 process.py
exports          original-ks.cfg       ps.py
[root@server6 ~]# rm -f pexpec.py

-

[root@server6 ~]# python ssh.py 
[root@server6 ~]# cat mylog.txt 
root@192.168.109.143's password: centos

Last login: Thu Aug 24 00:19:13 2017 from server6.example.com
[root@server7 ~]# ls /root
ls /root
anaconda-ks.cfg  demo1.py  initial-setup-ks.cfg  net.py           popen.py
A.py             Desktop   localhost.53420:      NS.py            process.py
CNAME.py         disk.py   mem.py                original-ks.cfg  ps.py
cpu.py           exports   MX.py                 other.py         psutil-2.0.0

-

[root@server6 ~]# cat ssh.py 
import sys
import pexpect
child=pexpect.spawn('ssh root@192.168.109.143')
fout=file('mylog.txt','w')
child.logfile=fout
child.expect('password:')
child.sendline('centos')
child.expect('#')
child.sendline('ls /root')
child.expect('#')

expect方法

  • expect(pattern,timeout,searchwindowsize)
  • 成员before
  • 成员after

-

[root@server6 ~]# python ssh.py 
before:root@192.168.109.143's 
after:password:
[root@server6 ~]# cat ssh.py 
import sys
import pexpect
child=pexpect.spawn('ssh root@192.168.109.143')
fout=file('mylog.txt','w')
child.logfile=fout
#child.expect('(yes/no)?')
#child.sendline('yes')
child.expect('password:')
child.sendline('centos')
print "before:"+child.before
print "after:"+child.after
  • read

-

send(self,s)发送命令,不会车
sendline(self,s='')发送命令,回车
sendcontrol(self,char)发送控制符
sendof()发送eof

run函数

  • 进行封装的调用外部命令的函数,类似os.system或os.popen;
  • 使用run()可同时获得命令的输出结果及命令的退出状态 pexpect.run(command,timeout=-1,withexitstatus=False,events=None,extra_args=None,logfile=None.cwd=None,env=None)
  • command:系统已知任意命令
  • events:字典

-

[root@server6 ~]# cat test.py 
from pexpect import *
run('scp ssh.py root@192.168.109.143:', events={'(?i)password' : 'centos\n'} )
[root@server6 ~]# python test.py 
[root@server7 ~]# ls
tmp
[root@server7 ~]# ls
ssh.py  tmp

派生类pxssh

功能

  • 针对ssh会话操作上再做一层封装,提供与基类更加直接的操作方法

pxssh类定义

class pexpect.pxssh.pxssh(timeout=30,maxread=2000,searchwindowsize=None,logfile=None,cwd=None,env=None)

常用方法

  • login():建立ssh连接
  • logout():断开连接
  • prompt():等待系统提示符,用于等待命令执行结束

执行过程

  • 使用login()方法与远程主机建立连接,再通过sendline()方法发送执行的命令,prompt()方法等待命令执行结束且出现系统提示符,最后使用logout()方法断开连接。

-

[root@server6 ~]# python test.py 
hostname:192.168.109.143
username:root
please input password:
uptime
 18:08:13 up  8:02,  2 users,  load average: 0.06, 0.03, 0.05

ls -l
total 4
-rw-r--r-- 1 root root 277 Aug 24 17:30 ssh.py
drwxr-xr-x 5 root root 320 Aug 24 17:10 tmp

df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda3       18555904 6128564  12427340  34% /
devtmpfs          485292       0    485292   0% /dev
tmpfs             499968     100    499868   1% /dev/shm
tmpfs             499968   38528    461440   8% /run
tmpfs             499968       0    499968   0% /sys/fs/cgroup
/dev/sda1         303780  154756    149024  51% /boot
tmpfs              99996      16     99980   1% /run/user/42
tmpfs              99996       0     99996   0% /run/user/0

-

[root@server6 ~]# cat test.py 
import pxssh
import getpass
try:
        s=pxssh.pxssh()
        hostname=raw_input('hostname:')
        username=raw_input('username:')
        password=getpass.getpass('please input password:')
        s.login(hostname,username,password)
        s.sendline('uptime')
        s.prompt()# ?
        print s.before
        s.sendline('ls -l')
        s.prompt()
        print s.before
        s.sendline('df')
        s.prompt()
        print s.before
        s.logout()
except pxssh.ExceptionPxssh,e:
        print "pxssh failed on login."
        print str(e)

例子

  • 实现自动化FTP操作

-

步骤1,在server6(192.168.109.142)搭建ftp
yum install -y vsftpd
步骤2,查看配置文件,匿名用户的权限(登录,下载)
anonymous_enable=YES
anon_upload_enable=YES
步骤3,开启服务
service vsftpd start
步骤4,准备测试文件
cd /var/ftp/pub
echo "hello">file.txt
  • 手动到ftp服务器下载东西

-

[root@server7 ~]# ftp 192.168.109.142
Connected to 192.168.109.142 (192.168.109.142).
220 (vsFTPd 3.0.2)
Name (192.168.109.142:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> bin
200 Switching to Binary mode.
ftp> get file.txt
local: file.txt remote: file.txt
227 Entering Passive Mode (192,168,109,142,163,50).
550 Failed to open file.
ftp> ls
227 Entering Passive Mode (192,168,109,142,34,224).
150 Here comes the directory listing.
drwxr-xr-x    2 0        0              22 Aug 25 01:36 pub
226 Directory send OK.
ftp> cd pub
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,109,142,98,198).
150 Here comes the directory listing.
-rw-r--r--    1 0        0               6 Aug 25 01:36 file.txt
226 Directory send OK.
ftp> get file.txt
local: file.txt remote: file.txt
227 Entering Passive Mode (192,168,109,142,68,111).
150 Opening BINARY mode data connection for file.txt (6 bytes).
226 Transfer complete.
6 bytes received in 0.00144 secs (4.17 Kbytes/sec)
ftp> exit
221 Goodbye.

-

[root@server7 ~]# ls
file.txt  ssh.py  tmp
  • 自动到pub目录下载指定文件

-

[root@server7 ~]# python ftp.py 
226 Directory send OK.
ftp> get file.txt
local: file.txt remote: file.txt
227 Entering Passive Mode (192,168,109,142,22,117).
150 Opening BINARY mode data connection for file.txt (6 bytes).
226 Transfer complete.
6 bytes received in 0.000135 secs (44.44 Kbytes/sec)
ftp> exit
221 Goodbye.
  • 一定要注意是否首次scp拷贝东西

-

    [root@server7 ~]# cat ftp.py 
    from __future__ import unicode_literals
    import pexpect
    import sys
    child=pexpect.spawnu('ftp server6')
    child.sendline('anonymous')
    child.expect('(?i)password')
    child.sendline('\n')
    child.expect('ftp>')
    child.sendline('bin')
    child.expect('ftp>')
    child.sendline('dir')
    if child.expect('pub')==0:
            child.sendline('cd pub')
            if child.expect('OK.')==0:
                    child.sendline('ls')
                    if child.expect('file.txt')==0:
                            child.sendline('get file.txt')
    sys.stdout.flush()
    child.sendline('exit')
    child.interact()
    child.close()


[root@server6 ~]# cat tar.py 
import pexpect
import sys
ip="192.168.109.143"
user="root"
password="centos"
target_file="/etc/vsftpd/vsftpd.conf"
child=pexpect.spawn('/usr/bin/ssh',[user+'@'+ip])
fout=file('mylog.txt','w')
child.logfile=fout
try:
        #if child.expect('(?i)id_rsa')==0:
        #       child.sendline('\n')
        child.expect('(?i)password')
        child.sendline(password)
        child.expect('#')
        child.sendline('tar -czf /tmp/vsftpd.tar.gz '+target_file)
        child.expect('#')
        child.sendline('exit')
        fout.close()
except EOF:
        print "except EOF"
except TIMEOUT:
        print "expect  TIMEOUT"
child=pexpect.spawn('/usr/bin/scp',[user+'@'+ip+':/tmp/vsftpd.tar.gz','/home'])
fout=file('mylog.txt','a')
child.logfile=fout
try:
        #if child.expect('(?i)id_rsa')==0:
        #       child.sendline('\n')
        child.expect('(?i)password')
        child.sendline(password)
        child.expect(pexpect.EOF)
except pexpect.EOF:
        print "except EOF"
except TIMEOUT:
        print "expect  TIMEOUT"
  • 结果

-

[root@server6 ~]# python tar.py 
[root@server6 ~]# cat mylog.txt 
root@192.168.109.143's password: centos

Last login: Thu Aug 24 23:36:38 2017 from server6.example.com
[root@server7 ~]# tar -czf /tmp/vsftpd.tar.gz /etc/vsftpd/vsftpd.conf
tar -czf /tmp/vsftpd.tar.gz /etc/vsftpd/vsftpd.conf
tar: Removing leading `/' from member names
[root@server7 ~]# exit
root@192.168.109.143's password: centos

vsftpd.tar.gz                                   0%    0     0.0KBvsftpd.tar.gz                                 100% 2302     2.3KB/s   00:00  
[root@server7 home]# ls
centos  ly  vsftpd.tar.gz
 类似资料: