人类的孤独像是一种与生俱来的残疾。

人生苦短,快用Python——使用pexpect模块进行命令行程序自动交互

Python/Shell smallfish 2023℃

原文来自:https://www.ibm.com/developerworks/cn/linux/l-cn-pexpect1/index.html

侵删。具体内容可以参见原文,本文仅作为笔记。

Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块。 Pexpect 可以用来和像 ssh、ftp、passwd、telnet 等命令行程序进行自动交互。本文章介绍 Pexpect 的主要用法和在实际应用中的注意点。 Python 语言的爱好者,系统管理人员,部署及测试人员都能使用 Pexpect 在自己的工作中实现与命令行交互的自动化。

1、pexpect模块仅在类unix环境中可用,windows暂不可用,或使用Cygwin替代方案。

2、run()函数可以用来执行命令,其作用与python os.system()类似,它是通过Pexpect类实现的,如果路径没有完全给出,则run会使用which命令尝试搜索该命令的路径。

run(command,timeout=-1,withexitstatus=False,events=None, extra_args=None,logfile=None, cwd=None, env=None)

3、spawn()类,用以实现子程序的启动。它有丰富的方法与子程序交互从而实现用户对子程序的控制。

它可以记录日志,将日志指向标准输出,记录输出日志等。

4、使用expect控制子程序。为了控制子程序,等待子程序产生特定输出,做出特定的响应,可以使用expect方法。expect 不断从读入缓冲区中匹配目标正则表达式,当匹配结束时 pexpect 的 before 成员中保存了缓冲区中匹配成功处之前的内容, pexpect 的 after 成员保存的是缓冲区中与目标正则表达式相匹配的内容。

5、send()/sendline()/sendcontrol()这些方法用来向子程序发送命令,模拟输入命令的行为。

6、interact()使用Pexpect让出控制权,用户可以继续当前的会话控制子程序。用户可以输入特定的退出字符跳出,其默认值为“^]”。

实例应用

清单 18. ftp 交互的实例:
# This connects to the openbsd ftp site and
# downloads the README file.
import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('cd pub/OpenBSD')
child.expect('ftp> ')
child.sendline ('get README')
child.expect('ftp> ')
child.sendline ('bye')
import re,sys,os
from pexpect import *

def telnet_login(server,user, passwd,shell_prompt= “#|->”):  
    """  
    @summary: This logs the user into the given server.
    It uses the 'shell_prompt' to try to find the prompt right after login.
    When it finds the prompt it immediately tries to reset the prompt to '#UNIQUEPROMPT#'
    more easily matched.  
    @return: If Login successfully ,It will return a pexpect object    
    @raise exception: RuntimeError will be raised when the cmd telnet failed or the user
    and passwd do not match  
    @attention:1. shell_prompt should not include '$',on some server, after sendline
                  (passwd)   the pexpect object will read a '$'.  
    2.sometimes the server's output before its shell prompt will contain '#' or
     '->'  So the caller should kindly assign the shell prompt  
    """  
    if not server or not user \  
          or not passwd or not shell_prompt:  
        raise RuntimeError, "You entered empty parameter for telnet_login "  
      
    child = pexpect.spawn('telnet %s' % server)  
    child.logfile_read = sys.stdout  
    index = child.expect (['(?i)login:', '(?i)username', '(?i)Unknown host'])  
    if index == 2:  
        raise RuntimeError, 'unknown machine_name' + server  
    child.sendline (user)  
    child.expect ('(?i)password:')  
    child.logfile_read = None  # To turn off log
    child.sendline (passwd)  
      
    while True:  
        index = child.expect([pexpect.TIMEOUT,shell_prompt])  
        child.logfile_read = sys.stdout  
        if index == 0:  
            if re.search('an invalid login', child.before):  
                raise RuntimeError, 'You entered an invalid login name or password.'
        elif index == 1:  
            break      
    child.logfile_read = sys.stdout # To tun on log again
    child.sendline(“PS1=#UNIQUEPROMPT#”)  
    #This is very crucial to wait for PS1 has been modified successfully  
    #child.expect(“#UNIQUEPROMPT#”)  
    child.expect("%s.+%s" % (“#UNIQUEPROMPT#”, “#UNIQUEPROMPT#”))  
    return child
清单 20. pxssh 示例
import pxssh  
import getpass  
try: 
s = pxssh.pxssh() 
    hostname = raw_input('hostname: ')  
    username = raw_input('username: ')  
    password = getpass.getpass('password: ')  
    s.login (hostname, username, password)  
    s.sendline ('uptime')  # run a command  
    s.prompt()             # match the prompt  
    print s.before         # print everything before the propt.  
    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)

 

转载请注明:OpenMind » 人生苦短,快用Python——使用pexpect模块进行命令行程序自动交互

喜欢 (0)