I'm wring a python script for running some command. Some of those commands require user to input password, I did try to input data in their stdin, but it doesn't work, here is two simple python program represent the problem
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)
And here is the output
[guest@host01 ~]# python put_data.py
text1:text1
pass1:
It just stop there on the pass1 field. Here is the problem, why I can't put data to stdin to feed data to the password field? How can I write data to password fields?
You need the pexpect module for such cases.
Pexpect is a Python module for
spawning child applications and
controlling them automatically.
Pexpect can be used for automating
interactive applications such as ssh,
ftp, passwd, telnet, etc.
There's definitely no need for two classes to make something like this. All you'd need to do is create another method in put_data.py called init_() and then do something along the lines of:
x = raw_input('text1:')
y = getpass.getpass('pass1:')
z = getpass.getpass('pass2:')
Then you can just use pexpect to do the rest:
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
tada! Granted you'll probably get a ton of errors with code like that. You should always utilize the provided methods, if you're using linux it may just be easier to run os.system("passwd") and let the shell take care of the rest. Also, if at all possible always avoid using getpass, it's a funky obsolete method and can mess things up down the road.