Reputation: 327
I've been looking for an answer to the question above.
The Popen command should not return anything, its simply asking for "do you want to continue?" (yes) and the "admin password" taken from a local database.
Current code state is: Everything works fine but asks me the second input, first input passes through.
So, I'm open to suggestions and willing to try your helps. Any help would be appreciated.
#Input 1
p = Popen(["foo", "bar"], stdin=PIPE, universal_newlines=True)
try:
p.stdin.write('yes' + linesep)
except IOError as e:
if e.errno == errno.EPIPE or e.errno == errno.EINVAL:
break
else:
raise
p.stdin.flush()
#Input 2
try:
p.stdin.write(KeyPass + linesep)
except IOError as e:
if e.errno == errno.EPIPE or e.errno == errno.EINVAL:
break
else:
raise
p.stdin.flush()
p.stdin.close()
p.wait()
Upvotes: 1
Views: 1641
Reputation: 41
you can use communicate()
instead of write()
p.communicate(input='{}\n{}'.format('yes', KeyPass).encode('utf-8'))
Upvotes: 0
Reputation: 414795
its simply asking for "do you want to continue?" (yes) and the "admin password"
To answer "yes"
if the child process asks "...continue?" and to write a password when prompted:
import pexpect # $ pip install pexpect
output, status = pexpect.run('foo bar',
events={r'continue\?': 'yes\n', 'password': 'p4$$W__rd\n'},
withexitstatus=1)
pexpect
makes sure that even if the child process writes/reads directly to/from a terminal (outside process' stdout/stdin), you'll see its output and it receives your input.
Upvotes: 0
Reputation: 366063
It does not echo the password neither asterisks.
This means you can't drive it through stdin
. What you're trying to do is just not possible that way.
See if there's another way to give it a password—maybe on the command line, or through the environment—or to avoid giving it a password (e.g., with ssh
you can exchange keys instead of passing passwords).
If not, your only option is to give it a pseudo-TTY instead of a regular pipe. (Even this isn't guaranteed to work, but it's likely to work, and worth trying.)
There are three ways to do that from Python: os.openpty
, os.forkpty
, and the pty
module. In theory, forkpty
is the most platform-specific, but in practice, because pty
is only tested on Linux, and openpty
requires you to do other platform-specific stuff to actually do anything useful with it, I'd start with forkpty
. The code looks like this:
pid, fd = os.forkpty()
if not pid:
# We're in the child here, but we still have to launch the program
os.execlp('foo', 'bar')
# This code is still in the parent.
Now, the parent can use os.read(fd)
and os.write(fd)
to talk to the child, and the child will see it as coming from the TTY. And when the child is done, you have to os.waitpid(pid)
it. Just remember that you're dealing with low-level file I/O here—no decoding to Unicode, no universal newlines, and, most of all, no buffering. This can be tricky to deal with, but you have to deal with it.
Or, of course, you can use a library like pexpect
, which can use a PTY and hide all the details from you. I'm not sure why you're resistant to this idea, but when you get frustrated trying to deal with forkpty
, maybe give it another chance.
Upvotes: 1