1

I am executing a script which prompts for 2 values one after the other. I want to pass the values from the script itself as I want to automate this.

Using the subprocess module, I can easily pass one value:

suppression_output = subprocess.Popen(cmd_suppression, shell=True,
        stdin= subprocess.PIPE,
        stdout= subprocess.PIPE).communicate('y') [0]

But passing the 2nd value does not seem to work. If I do something like this:

suppression_output = subprocess.Popen(cmd_suppression, shell=True,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE).communicate('y/r/npassword')[0]
Gary Fixler
  • 5,632
  • 2
  • 23
  • 39
Subhasish
  • 43
  • 2
  • 6

2 Answers2

2

You should use \n for the new line instead of /r/n -> 'y\npassword'

As your question is not clear, I assumed you have a program which behaves somewhat like this python script, lets call it script1.py:

import getpass
import sys
firstanswer=raw_input("Do you wish to continue?")
if firstanswer!="y":
  sys.exit(0)   #leave program
secondanswer=raw_input("Enter your secret password:\n")
#secondanswer=getpass.getpass("Enter your secret password:\n")
print "Password was entered successfully"
#do useful stuff here...
print "I should not print it out, but what the heck: "+secondanswer

It asks for confirmation ("y"), then wants you to enter a password. After that it does "something useful", finally prints the password and then exits

Now to get the first program to be run by a second script script2.py it has to look somewhat like this:

import subprocess
cmd_suppression="python ./testscript.py"
process=subprocess.Popen(cmd_suppression,shell=True\
,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
response=process.communicate("y\npassword")
print response[0]

The output of script2.py:

$ python ./script2.py
Do you wish to continue?Enter your secret password:
Password was entered successfully
I should not print it out, but what the heck: password

A problem can most likely appear if the program uses a special method to get the password in a secure way, i.e. if it uses the line I just commented out in script1.py

secondanswer=getpass.getpass("Enter your secret password:\n")

This case tells you that it is probably not a good idea anyway to pass a password via a script.

Also keep in mind that calling subprocess.Popen with the shell=True option is generally a bad idea too. Use shell=False and provide the command as a list of arguments instead:

cmd_suppression=["python","./testscript2.py"]
process=subprocess.Popen(cmd_suppression,shell=False,\
stdin=subprocess.PIPE,stdout=subprocess.PIPE)

It is mentioned a dozen times in the Subprocess Documentation

MaSp
  • 291
  • 1
  • 6
  • Thanks for the explanation. I will make my question a little more clear. I have a python script which runs a command which prompts me two times: Suppress nodes:? [y/N]: and Enter schen password: I want to respond to these prompts automatically from the script when running it from the subprocess module. Is that possible? I am only able to pass the first answer 'y' with communicate()..how to pass the second one? – Subhasish Mar 18 '14 at 04:24
  • It should work right away if you change communicate('y/r/npassword') into communicate('y\npassword') or maybe even communicate('y\r\npassword') (under Windows). It would be most helpful if you were to provide the error message you get (if any). My script2.py has exactely the functionality you want to have for your script and it works fine on my machine (linux, python 2.7.5+) – MaSp Mar 18 '14 at 04:36
  • It still stops at the second prompt. Here is my code: http://pastebin.com/LA2Dcbvv It has two prompts: Suppress nodes:? [y/N]: and Enter schen password: . It accepts the 'y' automatically but prompts for the password (password is test123 which i hard coded in the script) – Subhasish Mar 18 '14 at 04:58
  • Well then it seems that the program doesn't take the password from stdin, so using subprocess will not work here. That is the problem I mentioned in my answer. A solution would be to use the module pexpect instead. Look at this Post, the problem is quite similar to yours: http://stackoverflow.com/questions/230845/make-python-enter-password-when-running-a-csh-script – MaSp Mar 18 '14 at 05:24
  • A brief introduction to pexpect can be found here: http://www.pythonforbeginners.com/systems-programming/how-to-use-the-pexpect-module-in-python – MaSp Mar 18 '14 at 05:32
1

Try os.linesep:

import os
from subprocess import Popen, PIPE

p = Popen(args, stdin=PIPE, stdout=PIPE)
output = p.communicate(os.linesep.join(['the first input', 'the 2nd']))[0]
rc = p.returncode

In Python 3.4+, you could use check_output():

import os
from subprocess import check_output

input_values = os.linesep.join(['the first input', 'the 2nd']).encode()
output = check_output(args, input=input_values)

Note: the child script might ask for a password directly from the terminal without using subprocess' stdin/stdout. In that case, you might need pexpect, or pty modules. See Q: Why not just use a pipe (popen())?

import os
from pexpect import run # $ pip install pexpect

nl = os.linesep
output, rc = run(command, events={'nodes.*:': 'y'+nl, 'password:': 'test123'+nl},
                 withexitstatus=1)
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • no..the same thing..it accepts 'y' for the first prompt but stops at the password..code.. http://pastebin.com/8L4T67d6 – Subhasish Mar 18 '14 at 05:11
  • @user3431143: [update your question](http://stackoverflow.com/posts/22468215/edit) and put the code where. Also "the same thing" is not informative. Describe what happens in detail (in your question). – jfs Mar 18 '14 at 05:12
  • The sript asks for 2 prompts which i want to supply automatically: Suppress nodes:? [y/N]: and Enter schen password: . It accepts the 'y' automatically for the 1st prompt but prompts for the password (password is test123 which i hard coded in the script) – Subhasish Mar 18 '14 at 05:19
  • @user3431143: do not put the relevant info in the comments. [update your question instead](http://stackoverflow.com/posts/22468215/edit) – jfs Mar 18 '14 at 05:21
  • @user3431143: do you see the password prompt on the terminal or is it blank? – jfs Mar 18 '14 at 05:23
  • I was seeing it in the terminal. But now after adding the pexpect part mentioned above, it is blank. No prompt is coming but the work it is supposed to do is also not happening. So i guess it is not executing. – Subhasish Mar 18 '14 at 05:32
  • @user3431143: if you use `pexpect` then it is just a matter of fine-tuning the `events` regexes and responses (e.g., try `nl = '\r\n'` and/or add `(?i)` to the regexes). Set short `timeout=1` and `logfile=sys.stdout` for debugging. – jfs Mar 18 '14 at 05:51