6

I'm writing a python script that executes a csh script in Solaris 10. The csh script prompts the user for the root password (which I know) but I'm not sure how to make the python script answer the prompt with the password. Is this possible? Here is what I'm using to execute the csh script:

import commands

commands.getoutput('server stop')
4
  • I had left out PIPE, the new version works... Commented Oct 23, 2008 at 19:05
  • First time to see commands in use. BTW -- you can use the getpass module to grab a password from command line without displaying it. Commented Oct 24, 2008 at 3:20
  • 1
    Obligatory link Commented Sep 2, 2013 at 18:28
  • 1
    Obligatory rebuttal to the "csh bashing" link Commented Oct 9, 2013 at 18:06

7 Answers 7

9

Have a look at the pexpect module. It is designed to deal with interactive programs, which seems to be your case.

Oh, and remember that hard-encoding root's password in a shell or python script is potentially a security hole :D

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, pexpect was the way to go... I posted the answer at the bottom of this thread.
5

Use subprocess. Call Popen() to create your process and use communicate() to send it text. Sorry, forgot to include the PIPE..

from subprocess import Popen, PIPE

proc = Popen(['server', 'stop'], stdin=PIPE)

proc.communicate('password')

You would do better do avoid the password and try a scheme like sudo and sudoers. Pexpect, mentioned elsewhere, is not part of the standard library.

3 Comments

This doesn't seem to work. I'll continue to investigate popen though.
I get the same response when using the PIPE like you recommend here. The script stops with the Password: prompt.
I don't think that this works because the csh script does exec su root -c "$cmd0 $*" to try to su to root. The su would be a different process than the 'server stop' script.
2
import pexpect
child = pexpect.spawn('server stop')
child.expect_exact('Password:')

child.sendline('password')

print "Stopping the servers..."

index = child.expect_exact(['Server processes successfully stopped.', 'Server is not running...'], 60)
child.expect(pexpect.EOF)

Did the trick! Pexpect rules!

Comments

1

Add input= in proc.communicate() make it run, for guys who like to use standard lib.

from subprocess import Popen, PIPE
proc = Popen(['server', 'stop'], stdin=PIPE)
proc.communicate(input='password')

Comments

0

Should be able to pass it as a parameter. something like:

commands.getoutput('server stop -p password')

1 Comment

our server stop script doesn't have a -p flag and won't likely be getting one.
0

This seems to work better:

import popen2

(stdout, stdin) = popen2.popen2('server stop')

stdin.write("password")

But it's not 100% yet. Even though "password" is the correct password I'm still getting su: Sorry back from the csh script when it's trying to su to root.

5 Comments

I think you inverted stdin and stdout.
Nope, from the API: Returns the file objects (child_stdout, child_stdin)
Just some FYI -- popen2 is "Deprecated since version 2.6: This module is obsolete. Use the subprocess module. Check especially the Replacing Older Functions with the subprocess Module section."
Yeah, I just noticed that. I switched my code back to the subprocess module. Thanks!
@darrick: I incorrectly referred to os.popen2 instead of popen2.popen2. Strangely enough, the order of stdin and stdout is different between the two libraries...
0

To avoid having to answer the Password question in the python script I'm just going to run the script as root. This question is still unanswered but I guess I'll just do it this way for now.

1 Comment

Would you please clean up and consolidate your answers?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.