在本文中,我们展示了如何使用pexpect模块在Python中管理交互式程序。
pexpect模块用于管理Python中的交互程序。它产生子应用程序,控制它们;并响应其输出中的预期模式。
pexpect模块用于自动化交互式应用程序,例如ssh、ftp或passwd。它可用于在不同服务器上自动执行软件包安装的设置脚本。
有两个基本函数:run和spawn。run函数执行命令并返回输出。它对于简单的交互很有用。
spawn函数是一个更强大的选项。它产生一个外部子命令,然后通过发送行和期待响应与子命令交互。
Python预期运行
run函数运行给定的命令;等待它完成;然后将所有输出作为字符串返回。标准错误输出包含在输出中。
#!/usr/bin/python
import pexpect
r = pexpect.run('echo hello')
print(str(r, 'UTF-8'))
在程序中,我们运行echo命令。
r = pexpect.run('echo hello')
我们运行echo命令。输出分配给r变量。
print(str(r, 'UTF-8'))
我们使用str函数将输出转换为字符串。
$ ./main.py hello
我们可以使用bytes.decode函数将bytes转换为str。
#!/usr/bin/python
import pexpect
r = pexpect.run('pwd').decode("utf-8")
print(f"The current working directory: {r.rstrip()}")
程序运行pwd程序,返回当前工作目录。
$ ./main.py The current working directory: /home/jano/Documents/prog/python/pexpect
Pythonpexpect日志文件
可以将输出重定向到日志文件中。run和spawnfunctions都有logfile参数。
#!/usr/bin/python
import pexpect
f = open('mylog.txt', 'wb')
pexpect.run('ls -l', logfile=f)
f.close()
在程序中,我们运行ls-l命令并将输出写入日志文件。
$ ./main.py $ head -3 mylog.txt total 60 -rw-rw-r-- 1 jano jano 120 dec 23 10:02 doc.txt -rwxrwxr-x 1 jano jano 418 dec 23 14:52 ftp2.py
Python预期产卵
spawn函数执行子程序并允许与其交互。
子项的expect函数在流中查找,直到匹配到模式。该模式已过载,可能需要多种类型。模式可以是字符串、EOF、已编译的正则表达式或任何这些类型的列表。字符串将被编译为正则表达式类型。
#!/usr/bin/python
import pexpect
child = pexpect.spawn('date')
child.expect(pexpect.EOF)
output = child.before
print(f'Today is : {output.decode("utf-8")}')
child.close()
在程序中,我们运行date命令来获取当前日期时间。
child = pexpect.spawn('date')
我们生成了date命令。
child.expect(pexpect.EOF)
对于pexpect.EOF,我们期望孩子已经退出。每次调用expect后,before和after属性将设置为子应用程序打印的文本。
output = child.before
before属性包含符合预期模式的所有文本。
$ ./main.py Today is : Å t 29. december 2022, 11:39:30 CET
PythonpexpectFTP示例
在下一个示例中,我们将与FTP命令进行交互。
#!/usr/bin/python
import pexpect
child = pexpect.spawn('ftp ftp.freebsd.org', encoding='utf-8')
child.expect('Name .*: ')
child.sendline('anonymous')
child.expect('Password:')
child.sendline('')
child.expect('ftp> ')
child.sendline('ls /pub/FreeBSD/')
child.expect('ftp> ')
print(child.before)
child.close()
在程序中,我们连接到匿名FTP服务器并发出ls命令。
child = pexpect.spawn('ftp ftp.freebsd.org', encoding='utf-8')
我们生成了ftp命令。使用此命令,我们连接到theftp.freebsd.org服务器。我们还提供编码。
child.expect('Name .*: ')
从服务器,我们期望一行以Namestringpattern开头,后跟一些字符。请注意,输入是正则表达式。
child.sendline('anonymous')
使用sendline,我们发送登录名。
child.expect('Password:')
child.sendline('')
我们期望密码提示并发送一个空密码,因为我们是匿名登录的。
child.sendline('ls /pub/FreeBSD/')
我们发出ls命令。
print(child.before)
我们打印ls命令的输出。
$ ./main.py ls /pub/FreeBSD/ 229 Entering Extended Passive Mode (|||51545|) 150 Here comes the directory listing. -rw-r--r-- 1 ftp ftp 4259 May 07 2015 README.TXT -rw-r--r-- 1 ftp ftp 35 Dec 29 10:45 TIMESTAMP drwxr-xr-x 9 ftp ftp 10 Dec 29 10:45 development -rw-r--r-- 1 ftp ftp 2995 Dec 29 10:00 dir.sizes drwxr-xr-x 22 ftp ftp 28 Dec 26 23:00 doc drwxr-xr-x 6 ftp ftp 6 Nov 10 15:01 ports drwxr-xr-x 12 ftp ftp 14 Dec 29 10:45 releases drwxr-xr-x 12 ftp ftp 14 Dec 09 20:25 snapshots 226 Directory send OK.
Python期待SSH
在下面的示例中,我们与ssh命令进行交互。
对于这个例子,我们必须有一个启用了密码认证的ssh账户。
#!/usr/bin/python
import pexpect
username = 'user7@192.168.0.25'
passwd = 'passwd'
child = pexpect.spawn(f'ssh {username}')
f = open('mylog.txt', 'wb')
child.logfile = f
child.expect('password:')
child.sendline(passwd)
i = child.expect(['Permission denied', '[#\$] '])
if i == 0:
print('failed to login. permission denied')
child.close()
elif i == 1:
print('connected')
child.sendline('uname -a')
child.expect('[#\$] ')
r = child.before.decode('utf-8')
child.write('exit')
child.close()
f.close()
我们连接到本地网络上的计算机并在主机上发出uname命令。
username = 'user7@192.168.0.25' passwd = 'passwd'
我们提供用户名和密码。
child = pexpect.spawn(f'ssh {username}')
我们使用ssh命令登录到主机。
f = open('mylog.txt', 'wb')
child.logfile = f
输出定向到日志文件。
child.expect('password:')
child.sendline(passwd)
计算机发送提示,我们发送密码。
i = child.expect(['Permission denied', '[#\$] '])
我们期望两种结果:权限被拒绝消息或标准提示。expect函数返回返回选项的索引。
elif i == 1:
print('connected')
child.sendline('uname -a')
child.expect('[#\$] ')
child.write('exit')
child.close()
如果登录成功,我们发出uname命令。稍后,我们发出exit命令终止连接。
在本教程中,我们介绍了Pythonpexpect模块。
列出所有Python教程。
