Im executing a module popen1.py and that calls popen2.py using the subprocess module,
but the output of popen2.py is not being displayed..When I display the child process id , its being displayed..Where does the output will be printed for popen2.py
call
child = subprocess.Popen(['python', 'popen2.py',"parm1='test'","parm='test1'"], shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
After the process completes, you can read child.stdout and child.stderr to get the data (since you pass subprocess.PIPE)
Alternatively, you can use oudata,errdata = child.communicate() which will wait for the subprocess to finish and then give you it's output as strings.
From a design perspective, it's better to import. I would refactor popen2.py as follows:
#popen2.py
# ... stuff here
def run(*argv):
#...
if __name__ == '__main__':
import sys
run(sys.argv[1:])
Then you can just import and run popen2.py in popen1.py:
#popen1.py
import popen2
popen2.run("parm1=test","parm=test1")
You can use child.stdout/child.stdin to comunicate with the process:
child = subprocess.Popen(['python', 'popen2.py',"parm1='test'","parm='test1'"], shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print child.stdout.readlines()
Related
How can I get string as return in this script?
main.py
from subprocess import Popen, PIPE
import os
import sys
child = os.path.join(os.path.dirname(__file__), "child.py")
command = [sys.executable, child, "test"]
process = Popen(command, stdout=PIPE, stdin=PIPE)
process.communicate()
print(process.poll())
child.py
import sys
def main(i):
return i*3
if __name__ == '__main__':
main(*sys.argv[1:])
I get only 0.
I think get response from print() and process.communicate() not the best way.
Processes can't return values in the same sense a function can.
They can only set an exit code (which is the 0 you get).
You can, however, use stdin and stdout to communicate between the main script and child.py.
To "return" something from a child, just print the value you want to return.
# child.py
print("Hello from child")
The parent would do something like this:
process = Popen(command, stdout=PIPE, stdin=PIPE)
stdout, stderr = Popen.communicate()
assert stdout == "Hello from child"
I want to interact with a process.
I can start the process and print out the first two lines (something like 'process successfully started').
Now I want to send a new command to the process which should return again something like 'command done' but nothing happens.
Please help me.
import subprocess
def PrintAndPraseOutput(output, p):
print(output)
if 'sucessfully' in output:
p.stdin.write('command')
cmd = ["./programm"]
p = subprocess.Popen(cmd, universal_newlines=True, shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
while p.poll() is None:
output = p.stdout.readline()
PrintAndPraseOutput(output, p)
Update:
same problem, no output after 'process successfully started'
import subprocess
def print_and_parse_output(output, p):
print(output)
if 'successfully' in output:
p.stdin.write('command\n')
with subprocess.Popen(["./programm"], universal_newlines=True, shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE) as proc:
while proc.poll() is None:
output = proc.stdout.readline()
print_and_parse_output(output, proc)
Your I/O should be line buffered, so PrintAndPraseOutput should send a '\n' at the end of the string.
BTW, you have a couple of spelling errors. That function should be named print_and_parse_output to conform to PEP-0008, and "successfully" has 2 c's.
def print_and_parse_output(output, p):
print(output)
if 'successfully' in output:
p.stdin.write('command\n')
When using subprocess like this it's a good idea to put it in a with statement. From the subprocess.Popen` docs:
Popen objects are supported as context managers via the with
statement: on exit, standard file descriptors are closed, and the
process is waited for.
with Popen(["ifconfig"], stdout=PIPE) as proc:
log.write(proc.stdout.read())
I'm the Python beginner and I have a task to do. I have to write a function, that opens a program (.bin), execute it so I can see the results. This program requires 2 arguments from command line. I used os.spawnv, but it doesn't work...
#!/usr/bin/python
import sys
import os
def calculate_chi():
if len(sys.argv)>1:
pdb_name=sys.argv[1]
dat_name=sys.argv[2]
crysol='/usr/bin/crysol'
os.spawnv(os.P_NOWAIT,crysol,[crysol,pdb_name,dat_name])
def main():
calculate_chi()
Can you help me?
You can use python subprocess module:
import subprocess
proc = subprocess.Popen(['/usr/bin/crysol', sys.argv[1], sys.argv[2]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while proc.poll() is None:
out = proc.stdout.readline() #read crystol's output from stdout and stderr
print out
retunValue = proc.wait() #wait for subprocess to return and get the return value
Use subprocess. It was intended to replace spawn.
import subprocess
subprocess.call([crysol, pdb_name, dat_name])
Everyone uses subprocess.Popen these days. An example call to your process would be
process = Popen(["/usr/bin/crysol", pdb_name, dat_name],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
I'm rather puzzled by why the code below doesn't print stdout and exit, instead it hangs (on windows). Any reason why?
import subprocess
from subprocess import Popen
def main():
proc = Popen(
'C:/Python33/python.exe',
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE
)
proc.stdin.write(b'exit()\r\n')
proc.stdin.flush()
print(proc.stdout.read(1))
if __name__=='__main__':
main()
Replace the following:
proc.stdin.flush()
with:
proc.stdin.close()
Otherwise the subprocess python.exe will wait forever stdin to be closed.
Alternative: using communicate()
proc = Popen(...)
out, err = proc.communicate(b'exit()\r\n')
print(out) # OR print(out[:1]) if you want only the first byte to be print.
I'm trying to launch an 'rsync' using subprocess module and Popen inside of a thread. After I call the rsync I need to read the output as well. I'm using the communicate method to read the output. The code runs fine when I do not use a thread. It appears that when I use a thread it hangs on the communicate call. Another thing I've noticed is that when I set shell=False I get nothing back from the communicate when running in a thread.
You didn't supply any code for us to look at, but here's a sample that does something similar to what you describe:
import threading
import subprocess
class MyClass(threading.Thread):
def __init__(self):
self.stdout = None
self.stderr = None
threading.Thread.__init__(self)
def run(self):
p = subprocess.Popen('rsync -av /etc/passwd /tmp'.split(),
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.stdout, self.stderr = p.communicate()
myclass = MyClass()
myclass.start()
myclass.join()
print myclass.stdout
Here's a great implementation not using threads:
constantly-print-subprocess-output-while-process-is-running
import subprocess
def execute(command):
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ''
# Poll process for new output until finished
for line in iter(process.stdout.readline, ""):
print line,
output += line
process.wait()
exitCode = process.returncode
if (exitCode == 0):
return output
else:
raise Exception(command, exitCode, output)
execute(['ping', 'localhost'])