如何将数据重定向到类似“getpass”的密码输入?

7 投票
2 回答
5927 浏览
提问于 2025-04-16 10:46

我正在写一个Python脚本,用来运行一些命令。其中有些命令需要用户输入密码。我尝试过在它们的标准输入(stdin)中输入数据,但没有成功。下面是两个简单的Python程序,展示了这个问题。

input.py

import getpass

print raw_input('text1:')
print getpass.getpass('pass1:')
print getpass.getpass('pass2:')

put_data.py

import subprocess
import getpass

def run(cmd, input=None):
    stdin=None
    if input:
        stdin=subprocess.PIPE
    p = subprocess.Popen(cmd, shell=True, stdin=stdin)
    p.communicate(input)
    if p.returncode:
        raise Exception('Failed to run command %r' % cmd)

input ="""text1
password1
password2
"""
run('python test.py', input)

这是输出结果:

[guest@host01 ~]# python put_data.py 
text1:text1
pass1:

程序在输入密码的地方就停住了。问题是,为什么我不能通过标准输入给密码字段输入数据呢?我该怎么才能给密码字段写入数据呢?

2 个回答

1

其实,做这样的事情根本不需要两个类。你只需要在put_data.py里再创建一个叫init_()的方法,然后可以像下面这样写:

x = raw_input('text1:')
y = getpass.getpass('pass1:')
z = getpass.getpass('pass2:')

接下来,你就可以用pexpect来完成剩下的工作:

child = pexpect.spawn(x, timeout=180)
while True:
   x = child.expect(["(current)", "new", "changed", pexpect.EOF, pexpect.TIMEOUT])
   if x is 0:
      child.sendline(y)
      time.sleep(1)
   if x is 1:
      child.sendline(z)
      time.sleep(1)
   if x is 2:
      print "success!"
      break

太棒了!不过要注意,这样的代码可能会出现很多错误。你应该尽量使用提供的方法。如果你是在Linux上,直接运行os.system("passwd")可能会更简单,让系统自己处理后面的事情。另外,如果可以的话,尽量避免使用getpass,这个方法有点过时,可能会在后续使用中引发麻烦。

2

在这种情况下,你需要使用pexpect这个模块。

Pexpect是一个Python模块,主要用于启动子程序并自动控制它们。你可以用Pexpect来自动化一些需要互动的应用,比如ssh、ftp、修改密码、telnet等等。

撰写回答