0

i am unable to pass in commands to stdin in python 3.2.5. I have tried with the following 2 approaches Also: This question is a continuation of a previous question.

from subprocess import Popen, PIPE, STDOUT
import time

p = Popen([r'fileLoc/uploader.exe'],shell = True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
p.stdin.write('uploader -i file.txt -d outputFolder\n')
print (p.communicate()[0])
p.stdin.close()

i also get numbers such as 96, 0, 85 returned to me when i try the code in the IDLE interpreter, along with errors such as from the print (p.communicate()[0])

Traceback (most recent call last):
  File "<pyshell#132>", line 1, in <module>
    p.communicate()[0]
  File "C:\Python32\lib\subprocess.py", line 832, in communicate
    return self._communicate(input)
  File "C:\Python32\lib\subprocess.py", line 1060, in _communicate
    self.stdin.close()
IOError: [Errno 22] Invalid argument

i have also used:

from subprocess import Popen, PIPE, STDOUT
    import time

    p = Popen([r'fileLoc/uploader.exe'],shell = True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
    p.communicate(input= bytes(r'uploader -i file.txt -d outputFolder\n','UTF-8'))[0]
    print (p.communicate()[0])
    p.stdin.close()

but with no luck.

Community
  • 1
  • 1
Rohit
  • 61
  • 3
  • 10

2 Answers2

0
  • don't use shell=True when passing the arguments as list.
  • stdin.write needs a bytes object as argument. You try to wire a str.
  • communicate() writes input to the stdin and returns a tuple with the otput of stdout and sterr, and it waits until the process has finished. You can only use it once, trying to call it a second time will result in an error.
  • are your sure the line you're writing should be passed to your process on stdin? Shouldn't it be the command you're trying to run?
mata
  • 67,110
  • 10
  • 163
  • 162
  • 1. Shell = True Solved 2. stdin.write: i solved this previously but i forgot to write it here, so now i have bytes(r'command','UTF-8') – Rohit Jun 26 '13 at 20:38
  • 3. the communicate() is what is giving me the biggest problems, i keep getting the IOError: [Errno 22] Invalid argument Error. I am only calling it once, and the format i am using is as follows: output = p.communicate(input = 'whatever the input is')[0] Even when i write: print (p.communicate()[0]) it still gives me IOError: [Errno 22] Invalid argument Error – Rohit Jun 26 '13 at 20:53
  • 4. it is a command i am trying to run, so i tried p = Popen([r'fileLoc/uploader.exe', 'command'],stdout=PIPE, stdin=PIPE, stderr=STDOUT) and p = Popen([r'fileLoc/uploader.exe'], stdout=PIPE, stdin=PIPE, stderr=STDOUT) and when i do p.stdout.readlines() i get the same login information – Rohit Jun 26 '13 at 20:54
  • have you tried `Popen([r'fileLoc/uploader.exe', '-i', 'file.txt', '-o', 'outputFolder'], ...)`? seems more reasonable to me. – mata Jun 26 '13 at 21:00
  • Mata, i am able to get past the login detail and to the login info section. So what this is doing is waits 5 secs then prompts me for my username, and then prompts me for my password. I tried p.stdin.write('username@email.com\n') But i dont think this is working, also when i type these statments in the idle interpreter, it returns some number such as 9, 30 ... can you explain what these are? – Rohit Jun 26 '13 at 21:34
  • 1
    `write` returns the number of bytes written to the stream, so that's what you're seeing in the interactive interperter session. Programs reading username/passwords are usually designed to read from a terminal, so often they don't work well when you send them data on stdin – mata Jun 26 '13 at 21:39
0
  1. Pass command arguments as arguments, not as stdin
  2. The command might read username/password from console directly without using subprocess' stdin. In this case you might need winpexpect or SendKeys modules. See my answer to a similar quesiton that has corresponding code examples

Here's an example how to start a subprocess with arguments, pass some input, and write merged subprocess' stdout/stderr to a file:

#!/usr/bin/env python3
import os
from subprocess import Popen, PIPE, STDOUT

command = r'fileLoc\uploader.exe -i file.txt -d outputFolder'# use str on Windows
input_bytes = os.linesep.join(["username@email.com", "password"]).encode("ascii")
with open('command_output.txt', 'wb') as outfile:
    with Popen(command, stdin=PIPE, stdout=outfile, stderr=STDOUT) as p:
        p.communicate(input_bytes)
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Sebastian, the program that i am trying to run, seems to freeze. – Rohit Jun 27 '13 at 13:27
  • @Rohit: It probably waits for input. To test it, do not redirect the stdout and see whether it stops (freezes) at a prompt (for username, password, etc). – jfs Jun 27 '13 at 14:13
  • ya i tried without the stdout = outfile, and it still seems to be frozen. i think there is an error with the starting the program itself – Rohit Jun 27 '13 at 14:46
  • I've meant that without the redirection, you should be able to see the subprocess output – to find out where it blocks – jfs Jun 27 '13 at 14:53
  • ya unfortunately, i am unable to see the output even without the redirection. i will some thing out, and see if they work, and then ill tell you – Rohit Jun 27 '13 at 15:10