Python Forum

Full Version: using subpocess for both reading and writing simultaneously
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hello
I have a very simple python code cpt.py:
for i in xrange(2):
   print i                 # line 2
   ans = raw_input()       # line 3
   print ans               # line 4
I want to write another python program that run cpt.py,
read the first item (printed by line 2) echo that value
which will be read by line 3, read the new line (line 4)
an do it twice since cpt.py loop 2 times.

I tried without success (since I am asking !)
cmd = "cpt.py"
p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)
p.stdout.readline(ans) # read the print i (line 2)
p.stdin.writelines(ans)# write it (line3)
p.stdout.readline(ans) # read the print a (line 3)
p.stdout.readline(ans) # read  (line 2) second time
p.stdin.writelines(ans)# write it(line 3) second time
p.stdout.readline(ans) # read (ligne 3) second time
Thank you very much

JC
For starters, you did not start your process right.
[python]
for i in xrange[2):

[\python]
Put the code in a function. The second program imports cpt and runs a function.
(May-29-2018, 06:16 PM)woooee Wrote: [ -> ]Put the code in a function. The second program imports cpt and runs a function that inputs the value and returns it to the calling program. Obviously you can do this a 2nd time for the 2nd input.

It does not import - it tries to run another program as an external process (and does not do it right in the process - pun intended Tongue ).

Please, try to understand the nature of the question before providing feedback
I think the problem is that 'cpt.py' is not an executable, so Popen fails in the execution.
As you have also redirected the stderr to a pipe you cannot see the error message that shall looks like "cpt.py: Not an executable"

In linux/mac the trick is as easy as adding the next header to cpt.py:
#!/usr/bin/env python3
# The previous line must be the 1st line, no spaces before the #.
And set the executable flag from the command line:
Output:
$> chmod +x cpt.py
For windows, refer to the official faq.

Other option is to run the script calling the python executable with something like:
cmd = "cpt.py"
with subprocess.Popen(['python', cmd], stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE) as p:
    txt = p.stdout.readline()  # read the print i (line 2)
    p.stdin.writelines(txt)    # write it (line3)
    a = p.stdout.readline()    # read the print a (line 3)
    b = p.stdout.readline(ans) # read  (line 2) second time
    p.stdin.writelines(b)      # write it(line 3) second time
    c = p.stdout.readline()    # read (ligne 3) second time
(May-30-2018, 08:08 AM)volcano63 Wrote: [ -> ]
(May-29-2018, 06:16 PM)woooee Wrote: [ -> ]Put the code in a function. The second program imports cpt and runs a function that inputs the value and returns it to the calling program. Obviously you can do this a 2nd time for the 2nd input.

It does not import - it tries to run another program as an external process (and does not do it right in the process - pun intended Tongue ).

Please, try to understand the nature of the question before providing feedback
Please try to understand the answer before criticizing. Do you want help or not?
(May-30-2018, 03:15 PM)woooee Wrote: [ -> ]Please try to understand the answer before criticizing. Do you want help or not?

I was not asking for help Snooty. And your second answer is as clueless as the first one. Have you ever used subprocess module, dear?
(May-30-2018, 09:31 AM)killerrex Wrote: [ -> ]I think the problem is that 'cpt.py' is not an executable, so Popen fails in the execution.
As you have also redirected the stderr to a pipe you cannot see the error message that shall looks like "cpt.py: Not an executable"

stderr definition is for the process itself - not for subprocess.Popen. The script did not start, among other reasons (let's assume that it has execution flag set and shebang line added, as per your advice):
  1. Path to the app was not set - like ./cpt.py
  2. Command string as parameter may only be provided when it is coupled with shell=True; with default value False list is required (as you have shown)
(May-30-2018, 08:11 PM)volcano63 Wrote: [ -> ]Command string as parameter may only be provided when it is coupled with shell=True; with default value False list is required (as you have shown)

I try not to use the shell=True mode... some bad experiences with the shell expansions.
I have done some additional tests and you are right that when you want to pass parameters with shell=False you need to pass them in a list. Is logical as Popen will try to blindly search for a file with the full name:
>>>with subprocess.Popen(['ls'], stdout=subprocess.PIPE) as p:
>>>    print(''.join(b.decode() for b in p.stdout.readlines()))
cpt.py
subp.py
>>> with subprocess.Popen('ls', stdout=subprocess.PIPE) as p:
>>>    print(''.join(b.decode() for b in p.stdout.readlines()))
cpt.py
subp.py
>>> with subprocess.Popen(['ls', '-r'], stdout=subprocess.PIPE) as p:
>>>    print(''.join(b.decode() for b in p.stdout.readlines()))
subp.py
cpt.py
>>> with subprocess.Popen('ls -r', stdout=subprocess.PIPE) as p:
>>>    print(''.join(b.decode() for b in p.stdout.readlines()))
Traceback (most recent call last):
  File "subp.py", line 27, in <module>
    with subprocess.Popen('ls -r', stdout=subprocess.PIPE) as p:
  File "/usr/lib64/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'ls -r': 'ls -r'
But for a python script that is in the same folder works in both ways as long as you set it executable.
If the script is not executable it produces an error like:
Error:
Traceback (most recent call last): File "subp.py", line 7, in <module> with subprocess.Popen(['./cpt.py'], stdout=subprocess.PIPE) as p: File "/usr/lib64/python3.6/subprocess.py", line 709, in __init__ restore_signals, start_new_session) File "/usr/lib64/python3.6/subprocess.py", line 1344, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) PermissionError: [Errno 13] Permission denied: './cpt.py'
Pages: 1 2