Python提供的os module容许我们在Python代码中调用shell命令,例如:
import os
os.system("ls /share/zlib.so")
则会返回/usr/lib目录下所有文件
-rw-r–r– 1 work work 46333 2007-04-17 15:52 zlib.so
结果同在命令提示符下执行
ls /usr/lib

如果要捕获输出,则使用
import os
text = os.popen("ls /usr/lib")
此时text保存shell输出的内容
print text
-rw-r–r– 1 work work 46333 2007-04-17 15:52 zlib.so

不幸的是,有时我们需要启动的程序需要进行一些交互,才能完成,例如在不同主机间拷贝文件的命令scp(需要输入密码),以及ftp工具lftp(虽然可以在登录时指定用户名和密码,仍然需要在交互方式下输入文件传输指令)等等。
此时os.system或者os.popen便无能为力了,因为它们无法模拟用户与所启动进程间的交互,不过我们可以利用pexpect来做。

pexpect是一个开源python项目,用来启动(spawn)其它程序,进行控制,模拟用户对输出进行响应。

pexpect的使用很简单,首先到这里下载:
http://sourceforge.net/project/showfiles.php?group_id=59762

tar zxf pexpect-2.1.tar.gz
cd pexpect-2.1
python setup.py install

然后就可以直接调用了
pexpect提供的函数主要有三个

pexpect.spawn(‘command’)
接收参数为一个字符串,也就是我们需要启动的程序,返回该程序的句柄

pexpect.expect(’some pattern’)
接收参数为一个正则表达式字符串,用来定位程序的返回结果
每次pexpect.expect()运行之后
就可以用pexpect.before和pexpect.after来获取expect定位之前和之后的响应文本

pexpect.send(‘command’)
接收参数为字符串,即用户输入的命令。pexpect.sendline(‘command’)的功能与此类似,只是会在命令后加上回车符

下面是一个lftp登录的例子:


#! /usr/bin/python
# -*- coding: utf-8 -*-

import pexpect
child = pexpect.spawn (‘lftp sftp://user:password@192.168.1.1′)
child.sendline (‘ls’)

child.expect (‘lftp .*> ‘)
print child.before   # 输出ls命令的结果.

child.sendline (‘get /share/somefile’)
child.expect (‘lftp .*> ‘)
print child.before   # 输出get的运行结果,判断文件是否正确获取.

child.sendline(‘quit;’)

类似的,我们可以写出在python中调用scp, ssh之类命令的程序。
更多的细节,请参考pexpect的文档
http://pexpect.sourceforge.net/


3条评论

  1. 越来越像个unix高手了

  2. 前些日子为了自动化sftp上传文件的流程,也准备用这个东西来着,后来嫌麻烦,所以现在往服务器传文件还手动着呢,懒惰就是无法进步啊

  3. 老兄 这个是不是不能在CRON 下运行呢? shell下的expect在CRON下运行不起来

发表评论

评论也有版权!

click to change验证码