0

Short version: How to execute a linux command which requires input after execution using Python?


Long version: I am building some fancy website stuff using Python to give my SVN server a way to be managed easier. (I can't remember all the linux commands)

So I want to create, delete and edit repo's and users using a webpage. I just came to the problem I do not know how to execute the following command using Python:

sudo htdigest /etc/apache2/dav_svn.htdigest "Subversion Repo" [username]

Well I know how to execute the command with os.system() or subprocess.Popen(), but the problem is that once that command is executed it asks to enter a password twice before continuing. Using multiple calls using os.system() or subprocess.Popen() won't work since they just create a new shell.

Is there a way in Python to let an argument be used once it is required?

LittleOne
  • 1,077
  • 1
  • 11
  • 21
  • *ssh* reads input from the terminal, which means that solutions using stdin are harder. You may want to look into *sshpass* which will read a password from stdin (or, MUCH LESS SECURELY, can take it as a command line argument). – Joshua Taylor Feb 19 '15 at 21:43
  • Running sudo from inside an automated script is not the recommended way of elevating privileges, but if you really want to do it, have you tried sending some `stdin` into the `Popen`? – dg99 Feb 19 '15 at 21:44
  • `subprocess.Popen()` does not have to open a new shell, by the way; it can run the executable directly. – Joshua Taylor Feb 19 '15 at 21:44
  • 1
    possible duplicate of [how do i write to a python subprocess' stdin](http://stackoverflow.com/questions/8475290/how-do-i-write-to-a-python-subprocess-stdin) – Iguananaut Feb 19 '15 at 21:45
  • Did not know that Popen could also 'reply' on the results. Maybe time to read full documentation. :) Thanks for the replies. Still have some issues with using communicate and the expecting string for password, so going with pexpect for now. – LittleOne Feb 19 '15 at 22:25

1 Answers1

1

It all depends, you can either use popen and handle bidirectional communication or if you are just waiting for known prompts, I would use pexpect:

So assuming, you wanted to spawn a program called myprocess and waited for the password prompt that had a > (greater than sign):

import pexpect
child = pexpect.spawn('myprocess')
child.expect('>')
child.sendline(password_var)
child.expect('>')
child.sendline(password_var)
Youn Elan
  • 2,379
  • 3
  • 23
  • 32