我一直在寻找上述问题的答案。
Popen命令不应该返回任何内容,它只是要求"你想继续吗?" (是)和"管理员密码"取自本地数据库。
当前的代码状态是:一切正常但是第二个输入,第一个输入通过。
所以,我愿意接受建议并愿意尝试你的帮助。任何帮助将不胜感激。
#Input 1
p = Popen(["foo", "bar"], stdin=PIPE, universal_newlines=True)
try:
p.stdin.write('yes' + linesep)
except IOError as e:
if e.errno == errno.EPIPE or e.errno == errno.EINVAL:
break
else:
raise
p.stdin.flush()
#Input 2
try:
p.stdin.write(KeyPass + linesep)
except IOError as e:
if e.errno == errno.EPIPE or e.errno == errno.EINVAL:
break
else:
raise
p.stdin.flush()
p.stdin.close()
p.wait()
答案 0 :(得分:1)
它不会回复密码,也不会反映星号。
这意味着您无法通过stdin
开车。你想要做的就是不可能那样。
查看是否有另一种方法可以给它一个密码 - 可能在命令行上,或通过环境 - 或者为了避免给它一个密码(例如,使用ssh
你可以交换密钥而不是传递密码)
如果没有,您唯一的选择是给它一个伪TTY而不是常规管道。 (即使这不能保证有效,但它可能有效,值得一试。)
有三种方法可以从Python执行此操作:os.openpty
,os.forkpty
和pty
模块。从理论上讲,forkpty
是特定于平台的,但在实践中,因为pty
仅在Linux上进行测试,而openpty
要求您执行其他特定于平台的内容以实际执行任何操作对它有用,我从forkpty
开始。代码如下所示:
pid, fd = os.forkpty()
if not pid:
# We're in the child here, but we still have to launch the program
os.execlp('foo', 'bar')
# This code is still in the parent.
现在,家长可以使用os.read(fd)
和os.write(fd)
与孩子交谈,孩子会将其视为来自TTY。孩子完成后,你必须os.waitpid(pid)
。请记住,你在这里处理低级文件I / O-没有解码到Unicode,没有通用换行符,最重要的是,没有缓冲。这可能很难处理,但你必须处理它。
或者,当然,您可以使用像pexpect
这样的库,它可以使用PTY并隐藏您的所有详细信息。我不确定为什么你会对这个想法产生抵触情绪,但当你因为试图处理forkpty
而感到沮丧时,也许再给它一次机会。
答案 1 :(得分:0)
它只是要求“你想继续吗?” (是)和“管理员密码”
如果子进程询问“...继续?”并在出现提示时写入密码,则回答"yes"
:
import pexpect # $ pip install pexpect
output, status = pexpect.run('foo bar',
events={r'continue\?': 'yes\n', 'password': 'p4$$W__rd\n'},
withexitstatus=1)
pexpect
确保即使子进程直接向/从终端写入/读取(进程外部进程'stdout / stdin),您也会看到它的输出并接收您的输入。
答案 2 :(得分:0)
您可以使用communicate()
代替write()
p.communicate(input='{}\n{}'.format('yes', KeyPass).encode('utf-8'))