Python 调用pg_dump时与pexpect的奇怪性
对不起,如果这是不允许的,我仍然是一个新手,所以请事先原谅我。我对我所注意到的行为感到好奇,希望得到一些信息 调用Python 调用pg_dump时与pexpect的奇怪性,python,pexpect,pg-dump,Python,Pexpect,Pg Dump,对不起,如果这是不允许的,我仍然是一个新手,所以请事先原谅我。我对我所注意到的行为感到好奇,希望得到一些信息 调用pg_dump时,您现在似乎需要传入一个用户升级的密码,因此我在这里的选项有限,使用选项是使用pexpect传入短语 不过,在发送了这行代码之后,什么也没有发生,当我登录到一个文件时,我所能看到的只是发送了密码,但没有输出。我对我的命令进行了双重/三重检查,并且它可以正常工作(使用cli),因此下面的代码段应该可以正常工作 我尝试读取child.logfile\u以确定预期的输出,我
pg_dump
时,您现在似乎需要传入一个用户升级的密码,因此我在这里的选项有限,使用选项是使用pexpect
传入短语
不过,在发送了这行代码之后,什么也没有发生,当我登录到一个文件时,我所能看到的只是发送了密码,但没有输出。我对我的命令进行了双重/三重检查,并且它可以正常工作(使用cli),因此下面的代码段应该可以正常工作
我尝试读取child.logfile\u
以确定预期的输出,我的child.expect也正确
password='test'
cmd = 'pg_dump --host {host} --port {port} --dbname {db} --username {username}\
--file {filename} --table {table} --schema={schema}'.format(
host=host,
port=port,
db=db,
username=username,
filename=filename,
table=table,
schema=schema
)
child = pexpect.spawn(cmd)
child.expect('Password:')
child.sendline(password)
child.read()
我碰巧添加了一个child.read()
,然后砰的一声,我的文件如期导出。这对我来说是错误的,我尝试了一些不同的方法并通读了文档,但我似乎无法理解这实际上是可行的。我是说,根据
这将从文件中读取最多“大小”字节(如果读取在获取大小字节之前达到EOF,则读取的字节数将减少)。如果size参数为负数或省略,则读取所有数据,直到达到EOF。字节作为字符串对象返回。当立即遇到EOF时,返回一个空字符串
为什么这真的有效?我错过了什么?我觉得这是其中的一个案例,稍后它会轰炸我,因为我不知道引擎盖下到底发生了什么
我最好的猜测是EOF发生了一些奇怪的事情,命令实际上没有处理,但只要我使用child.read()
,它实际上就完成了命令?老实说,不确定。关键字是EOF。
正如您发布的pexpect文档摘录所暗示的,read
读取指定数量的字节或直到遇到EOF。在您的上下文中,这意味着它等待子进程发送EOF,这相当于进程终止
如果不调用read
,Python进程在子进程完成之前不会阻塞。它在子.sendline(密码)
调用返回后立即结束。
根据您使用spawn
的事实判断,我假设您正在POSIX平台上运行它。也就是说,你的孩子是个好孩子。
该类实现了\uuu del\uu
终结器,目的是
[…]确保没有任何系统资源处于打开状态
终结器将在实例上终止该方法。它关闭文件描述符并通过SIGINT、SIGHUP或(如果使用force=True
(默认值)SIGKILL调用来结束子进程
因此,当Python进程结束时,就在child.sendline(password)
返回之后,解释器开始清理其内存空间,并在进程中执行终结器。这会在pg_dump
命令开始写入输出文件之前终止该命令的执行。
在子进程完成之前,您必须阻止主进程<代码>阅读
当然可以,但你似乎对从孩子那里阅读并不特别感兴趣。你可以选择:
这会一直等到孩子退出。这是一个阻塞呼叫。这将不会从子项读取任何数据[…]
这就更有意义了,感谢你的冗长解释,这是一个完美的答案示例。CC:@shmee