Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块。 Pexpect 可以用来和像 ssh、ftp、passwd、telnet 等命令行程序进行自动交互。

pexpect模块在windows功能有限,在linux系统中用得比较多。

pexpect有两个类或方法用得比较多,一个是pexpect.run() 和pexpect.spawn()

pexpect.run()类似于os.system(),但pexpect.run()会返回执行结果

pexpect.spawn()这个类的功能比较强大,可以用于以下功能:

1. ftp 的使用(注:spawn、expect 和 sendline 的使用)

2. 记录 log(注:logfile、logfile_send和logfile_read的使用)

3. ssh 的使用

4. pxssh 的使用

5. telnet 的使用(注:interact 的使用)

使用注意事项:

1.不能使用linux命令中的管道符重定向符等

2.spawn里面的参数列表里面不要使用变量名

以下是实例:

1.pexpect连接ftp:

#!/usr/bin/env python

import pexpect

# 即将 ftp 所要登录的远程主机的域名

ipAddress = 'develperWorks.ibm.com'

# 登录用户名

loginName = 'root'

# 用户名密码

loginPassword = 'passw0rd'

# 拼凑 ftp 命令

cmd = 'ftp ' + ipAddress

# 利用 ftp 命令作为 spawn 类构造函数的参数,生成一个 spawn 类的对象

child = pexpect.spawn(cmd)

# 期望具有提示输入用户名的字符出现

index = child.expect(["(?i)name", "(?i)Unknown host", pexpect.EOF, pexpect.TIMEOUT])

# 匹配到了 "(?i)name",表明接下来要输入用户名

if ( index == 0 ):

# 发送登录用户名 + 换行符给子程序.

child.sendline(loginName)

# 期望 "(?i)password" 具有提示输入密码的字符出现.

index = child.expect(["(?i)password", pexpect.EOF, pexpect.TIMEOUT])

# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.

if (index != 0):

print "ftp login failed"

child.close(force=True)

# 匹配到了密码提示符,发送密码 + 换行符给子程序.

child.sendline(loginPassword)

# 期望登录成功后,提示符 "ftp>" 字符出现.

index = child.expect( ['ftp>', 'Login incorrect', 'Service not available',

pexpect.EOF, pexpect.TIMEOUT])

# 匹配到了 'ftp>',登录成功.

if (index == 0):

print 'Congratulations! ftp login correct!'

# 发送 'bin'+ 换行符给子程序,表示接下来使用二进制模式来传输文件.

child.sendline("bin")

print 'getting a file...'

# 向子程序发送下载文件 rmall 的命令.

child.sendline("get rmall")

# 期望下载成功后,出现 'Transfer complete.*ftp>',其实下载成功后,

# 会出现以下类似于以下的提示信息:

# 200 PORT command successful.

# 150 Opening data connection for rmall (548 bytes).

# 226 Transfer complete.

# 548 bytes received in 0.00019 seconds (2.8e+03 Kbytes/s)

# 所以直接用正则表达式 '.*' 将 'Transfer complete' 和提示符 'ftp>' 之间的字符全省去.

index = child.expect( ['Transfer complete.*ftp>', pexpect.EOF, pexpect.TIMEOUT] )

# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.

if (index != 0):

print "failed to get the file"

child.close(force=True)

# 匹配到了 'Transfer complete.*ftp>',表明下载文件成功,打印成功信息,并输入 'bye',结束 ftp session.

print 'successfully received the file'

child.sendline("bye")

# 用户名或密码不对,会先出现 'Login incorrect',然后仍会出现 'ftp>',但是 pexpect 是最小匹配,不是贪婪匹配,

# 所以如果用户名或密码不对,会匹配到 'Login incorrect',而不是 'ftp>',然后程序打印提示信息并退出.

elif (index == 1):

print "You entered an invalid login name or password. Program quits!"

child.close(force=True)

# 匹配到了 'Service not available',一般表明 421 Service not available, remote server has

# closed connection,程序打印提示信息并退出.

# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.

else:

print "ftp login failed! index = " + index

child.close(force=True)

# 匹配到了 "(?i)Unknown host",表示 server 地址不对,程序打印提示信息并退出

elif index == 1 :

print "ftp login failed, due to unknown host"

child.close(force=True)

# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出

else:

print "ftp login failed, due to TIMEOUT or EOF"

child.close(force=True)

2.记录log的日志代码

#!/usr/bin/env python

"""

This run a user specified command and log its result.

./command.py [-a] [-c command] {logfilename}

logfilename : This is the name of the log file. Default is command.log.

-a : Append to log file. Default is to overwrite log file.

-c : spawn command. Default is the command 'ls -l'.

Example:

This will execute the command 'pwd' and append to the log named my_session.log:

./command.py -a -c 'pwd' my_session.log

"""

import os, sys, getopt

import traceback

import pexpect

# 如果程序中间出错,打印提示信息后退出

def exit_with_usage():

print globals()['__doc__']

os._exit(1)

def main():

######################################################################

# Parse the options, arguments, get ready, etc.

######################################################################

try:

optlist, args = getopt.getopt(sys.argv[1:], 'h?ac:', ['help','h','?'])

# 如果指定的参数不是’ -a ’ , ‘ -h ’ , ‘ -c ’ , ‘ -? ’ , ‘ --help ’ ,

#‘ --h ’或’ --? ’时,会抛出 exception,

# 这里 catch 住,然后打印出 exception 的信息,并输出 usage 提示信息.

except Exception, e:

print str(e)

exit_with_usage()

options = dict(optlist)

# 最多只能指定一个 logfile,否则出错.

if len(args) > 1:

exit_with_usage()

# 如果指定的是 '-h','--h','-?','--?' 或 '--help',只输出 usage 提示信息.

if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]:

print "Help:"

exit_with_usage()

# 获取 logfile 的名字.

if len(args) == 1:

script_filename = args[0]

else:

# 如果用户没指定,默认 logfile 的名字是 command.log

script_filename = "command.log"

# 如果用户指定了参数 -a,如果之前该 logfile 存在,那么接下来的内容会附加在原先内容之后,

# 如果之前没有该 logfile,新建一个文件,并且接下来将内容写入到该文件中.

if '-a' in options:

fout = open (script_filename, "ab")

else:

# 如果用户没指定参数 -a,默认按照用户指定 logfile 文件名新建一个文件,然后将接下来将内容写入到该文件中.

fout = open (script_filename, "wb")

# 如果用户指定了 -c 参数,那么运行用户指定的命令.

if '-c' in options:

command = options['-c']

# 如果用户没有指定 -c 参数,那么默认运行命令'ls – l'

else:

command = "ls -l"

# logfile 文件的 title

fout.write ('==========Log Tile: IBM developerWorks China==========\n')

# 为接下来的运行命令生成一个 pexpect 的 spawn 类子程序的对象.

p = pexpect.spawn(command)

# 将之前 open 的 file 对象指定为 spawn 类子程序对象的 log 文件.

p.logfile = fout

# 命令运行完后,expect EOF 出现,这时会将 spawn 类子程序对象的输出写入到 log 文件.

p.expect(pexpect.EOF)

#open 完文件,使用完毕后,需关闭该文件.

fout.close()

return 0

if __name__ == "__main__":

try:

main()

except SystemExit, e:

raise e

except Exception, e:

print "ERROR"

print str(e)

traceback.print_exc()

os._exit(1)

注:

运行:./command.py -a -c who cmd.log

运行结束后,cmd.log 的内容为:

IBM developerWorks China

Root :0 2009-05-12 22:40

Root pts/1 2009-05-12 22:40 (:0.0)

Root pts/2 2009-07-05 18:55 (9.77.180.94)

logfile:

只能通过 spawn 类的构造函数指定。在 spawn 类的构造函数通过参数指定 logfile 时,表示开启或关闭 logging 。所有的子程序的 input 和 output 都会被 copy 到指定的 logfile 中。设置 logfile 为 None 表示停止 logging,默认就是停止 logging 。设置 logfile 为 sys.stdout,会将所有东西 echo 到标准输出。

logfile_read和logfile_send:

logfile_read:只用来记录 python 主程序接收到 child 子程序的输出,有的时候你不想看到写给 child 的所有东西,只希望看到 child 发回来的东西。 logfile_send:只用来记录 python 主程序发送给 child 子程序的输入 logfile、logfile_read 和 logfile_send 何时被写入呢? logfile、logfile_read 和 logfile_send 会在每次写 write 和 send 操作后被 flush 。

调用 send 后,才会往 logfile 和 logfile_send 中写入,sendline/sendcontrol/sendoff/write/writeline 最终都会调用 send,所以 sendline 后 logfile 中一定有内容了,只要此时 logfile 没有被 close 。

调用 read_nonblocking 后,才会往 logfile 和 logfile_read 中写入,expect_loop 会调用 read_nonblocking,而 expect_exact 和 expect_list 都会调用 expect_loop,expect 会调用 expect_list,所以 expect 后 logfile 中一定有内容了,只要此时 logfile 没有被 close 。

如果调用的函数最终都没有调用 send 或 read_nonblocking,那么 logfile 虽然被分配指定了一个 file,但其最终结果是:内容为空。见下例:

import pexpect

p = pexpect.spawn( ‘ ls -l ’ )

fout = open ('log.txt', "w")

p.logfile = fout

fout.close()

运行该脚本后,你会发现其实 log.txt 是空的,没有记录 ls -l 命令的内容,原因是没有调用 send 或 read_nonblocking,真正的内容没有被 flush 到 log 中。如果在 fout.close() 之前加上 p.expect(pexpect.EOF),log.txt 才会有 ls -l 命令的内容。

3.ssh的使用

#!/usr/bin/env python

"""

This runs a command on a remote host using SSH. At the prompts enter hostname,

user, password and the command.

"""

import pexpect

import getpass, os

#user: ssh 主机的用户名

#host:ssh 主机的域名

#password:ssh 主机的密码

#command:即将在远端 ssh 主机上运行的命令

def ssh_command (user, host, password, command):

"""

This runs a command on the remote host. This could also be done with the

pxssh class, but this demonstrates what that class does at a simpler level.

This returns a pexpect.spawn object. This handles the case when you try to

connect to a new host and ssh asks you if you want to accept the public key

fingerprint and continue connecting.

"""

ssh_newkey = 'Are you sure you want to continue connecting'

# 为 ssh 命令生成一个 spawn 类的子程序对象.

child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command))

i = child.expect([pexpect.TIMEOUT, ssh_newkey, 'password: '])

# 如果登录超时,打印出错信息,并退出.

if i == 0: # Timeout

print 'ERROR!'

print 'SSH could not login. Here is what SSH said:'

print child.before, child.after

return None

# 如果 ssh 没有 public key,接受它.

if i == 1: # SSH does not have the public key. Just accept it.

child.sendline ('yes')

child.expect ('password: ')

i = child.expect([pexpect.TIMEOUT, 'password: '])

if i == 0: # Timeout

print 'ERROR!'

print 'SSH could not login. Here is what SSH said:'

print child.before, child.after

return None

# 输入密码.

child.sendline(password)

return child

def main ():

# 获得用户指定 ssh 主机域名.

host = raw_input('Hostname: ')

# 获得用户指定 ssh 主机用户名.

user = raw_input('User: ')

# 获得用户指定 ssh 主机密码.

password = getpass.getpass()

# 获得用户指定 ssh 主机上即将运行的命令.

command = raw_input('Enter the command: ')

child = ssh_command (user, host, password, command)

# 匹配 pexpect.EOF

child.expect(pexpect.EOF)

# 输出命令结果.

print child.before

if __name__ == '__main__':

try:

main()

except Exception, e:

print str(e)

traceback.print_exc()

os._exit(1)

4. pxssh的使用

#!/usr/bin/env python

import pxssh

import getpass

try:

# 调用构造函数,创建一个 pxssh 类的对象.

s = pxssh.pxssh()

# 获得用户指定 ssh 主机域名.

hostname = raw_input('hostname: ')

# 获得用户指定 ssh 主机用户名.

username = raw_input('username: ')

# 获得用户指定 ssh 主机密码.

password = getpass.getpass('password: ')

# 利用 pxssh 类的 login 方法进行 ssh 登录,原始 prompt 为'$' , '#'或'>'

s.login (hostname, username, password, original_prompt='[$#>]')

# 发送命令 'uptime'

s.sendline ('uptime')

# 匹配 prompt

s.prompt()

# 将 prompt 前所有内容打印出,即命令 'uptime' 的执行结果.

print s.before

# 发送命令 ' ls -l '

s.sendline ('ls -l')

# 匹配 prompt

s.prompt()

# 将 prompt 前所有内容打印出,即命令 ' ls -l ' 的执行结果.

print s.before

# 退出 ssh session

s.logout()

except pxssh.ExceptionPxssh, e:

print "pxssh failed on login."

print str(e)

5.telnet 的使用

#!/usr/bin/env python

import pexpect

# 即将 telnet 所要登录的远程主机的域名

ipAddress = 'develperWorks.ibm.com'

# 登录用户名

loginName = 'root'

# 用户名密码

loginPassword = 'passw0rd'

# 提示符,可能是’ $ ’ , ‘ # ’或’ > ’

loginprompt = '[$#>]'

# 拼凑 telnet 命令

cmd = 'telnet ' + ipAddress

# 为 telnet 生成 spawn 类子程序

child = pexpect.spawn(cmd)

# 期待'login'字符串出现,从而接下来可以输入用户名

index = child.expect(["login", "(?i)Unknown host", pexpect.EOF, pexpect.TIMEOUT])

if ( index == 0 ):

# 匹配'login'字符串成功,输入用户名.

child.sendline(loginName)

# 期待 "[pP]assword" 出现.

index = child.expect(["[pP]assword", pexpect.EOF, pexpect.TIMEOUT])

# 匹配 "[pP]assword" 字符串成功,输入密码.

child.sendline(loginPassword)

# 期待提示符出现.

child.expect(loginprompt)

if (index == 0):

# 匹配提示符成功,输入执行命令 'ls -l'

child.sendline('ls -l')

# 立马匹配 'ls -l',目的是为了清除刚刚被 echo 回显的命令.

child.expect('ls -l')

# 期待提示符出现.

child.expect(loginprompt)

# 将 'ls -l' 的命令结果输出.

print child.before

print "Script recording started. Type ^] (ASCII 29) to escape from the script

shell."

# 将 telnet 子程序的执行权交给用户.

child.interact()

print 'Left interactve mode.'

else:

# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.

print "telnet login failed, due to TIMEOUT or EOF"

child.close(force=True)

else:

# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.

print "telnet login failed, due to TIMEOUT or EOF"

child.close(force=True)

更详细的情况请查看:

https://www.cnblogs.com/mmdln/p/9006274.html

python pexpect_python pexpect模块的使用相关推荐

  1. python pexpect telnet_使用python的pexpect模块,实现远程免密登录的示例

    说明 当我们需要用脚本实现,远程登录或者远程操作的时候,都要去解决如何自动输入密码的问题,一般来说有3种实现方式: 1).配置公钥私钥 2).使用shell下的命令,expect 3).使用pytho ...

  2. python sendline_python Pexpect模块的使用

    Pexpect简介 在讲解Pexpect之前,我们需要先了解一下Expect这个脚本语言,它是由TCL语言实现的,主要用于人机交互式对话的自动化控制,可以用来完成ssh.ftp.telnet等命令行程 ...

  3. python代替shell脚本_自动化shell脚本except与python的pexpect模块

    expect脚本 expect是什么 expect是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预.说白了,expect就是一套用来实现自动交互功能的软件. 在实际工作中,我们运行命令. ...

  4. Python的Pexpect模块详解

    对于存在交互过程的远程访问,如ssh, ftp, mencoder, passwd等,通过Pexpect模块可以根据应用的输出控制交互过程,从而提高容错性. Pexpect模块首先通过生成子应用以代理 ...

  5. python pexpect_Python Pexpect库的简单使用方法

    简介 最近需要远程操作一个服务器并执行该服务器上的一个python脚本,查到可以使用Pexpect这个库.记录一下. 什么是Pexpect?Pexpect能够产生子应用程序,并控制他们,并能够通过期望 ...

  6. python pexpect_python pexpect总结

    基本使用流程 pexpect 的使用说来说去,就是围绕3个关键命令做操作: 首先用 spawn 来执行一个程序 然后用 expect 来等待指定的关键字,这个关键字是被执行的程序打印到标准输出上面的 ...

  7. python pexpect_python pexpect

    安装 https://pypi.python.org/pypi/pexpect 下载pexpect 4.0.1 放到ubuntu中解压 tar -xzvf pexpect 4.0.1.tar.gz 到 ...

  8. python的pexpect模块的应用

    pexpect简介 pexpect是一个纯pyth实现的模块,pexpect可以某些交互式子进程进行交互从而代替手工操作.比如使用passwd命令需要人工输入密码,如果使用pexpect可以通过sen ...

  9. Python Pexpect 模块使用说明

    背景介绍 Expect 程序主要用于人机对话的模拟,就是那种系统提问,人来回答 yes/no ,或者账号登录输入用户名和密码等等的情况.因为这种情况特别多而且繁琐,所以很多语言都有各种自己的实现.最初 ...

最新文章

  1. 最近のWebSocket事情についてまとめとく
  2. 关于JAVA项目中CLASSPATH路径详解
  3. sell02 展现层编写
  4. JAVA中this用法小结
  5. 编译php5遇到iconv错误的解决方法
  6. Java中的中介器设计模式-示例教程
  7. linux字符驱动之概念介绍
  8. Linux内核工程师是怎么步入内核殿堂的?
  9. jdbctemplate 开启事务_浅入浅出 Spring 事务传播实现原理
  10. 乐鑫esp8266的串口通讯驱动源文件,nonos和rtos版本
  11. win 7 双击themepack主题包没反应的完美解决方法!
  12. 2022年互联网+全国大学生创新创业大赛解读
  13. robotframework使用之 下拉框的选择的几种用法
  14. 为资产分类定义折旧范围_2广东省农村集体经济组织固定资产分类及折旧办法(4月15日)...
  15. python进制转换问题“输入十进制整数和欲转换的进制数r,将十进制转换为r进制数(r>=2)”
  16. Python爬虫:给我一个链接,西瓜视频随便下载
  17. lora手持终端PDA设备
  18. 易语言调用大漠插件对雷电模拟器进行后台绑定源码
  19. 干货 | 如何搭建小型视频点播网站
  20. 什么是信令?什么是信令网?(转)

热门文章

  1. STM32CubeIDE设置
  2. 百科不全书之Python网络爬虫1
  3. 创建型模式-工厂方法模式(二)
  4. JSTL --图文并茂详解(全) 轻松掌握
  5. Rust AES加密、解密工具
  6. Android如何设置为设备拥有者device-owner?
  7. Python_缴纳党费,按收入不同缴纳不同的百分比计算
  8. 深度linux live,LinuxDeepin/用LinuxLive USB Creator安装LinuxDeepin
  9. 个人作业二-软件案例分析
  10. css画表格多级表头,element UI实现动态生成多级表头