0

I would like to run an exe from this directory:/home/pi/pi_sensors-master/bin/Release/ This exe is then run by tying mono i2c.exe and it runs fine.

I would like to get this output in python which is in a completely different directory.

I know that I should use subprocess.check_output to take the output as a string.

I tried to implement this in python:

import subprocess
import os


cmd = "/home/pi/pi_sensors-master/bin/Release/"
os.chdir(cmd)
process=subprocess.check_output(['mono i2c.exe'])
print process

However, I received this error: enter image description here

The output would usually be a data stream with a new number each time, is it possible to capture this output and store it as a constantly changing variable?

Any help would be greatly appreciated.

Hamoudy
  • 553
  • 2
  • 8
  • 23

1 Answers1

2

Your command syntax is incorrect, which is actually generating the exception. You want to call mono i2c.exe, so your command list should look like:

subprocess.check_output(['mono', 'i2c.exe']) # Notice the comma separation.

Try the following:

import subprocess
import os

executable = "/home/pi/pi_sensors-master/bin/Release/i2c.exe"

print subprocess.check_output(['mono', executable])

The sudo is not a problem as long as you give the full path to the file and you are sure that running the mono command as sudo works.

I can generate the same error by doing a ls -l:

>>> subprocess.check_output(['ls -l'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 537, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

However when you separate the command from the options:

>>> subprocess.check_output(['ls', '-l'])
# outputs my entire folder contents which are quite large.

I strongly advice you to use the subprocess.Popen -object to deal with external processes. Use Popen.communicate() to get the data from both stdout and stderr. This way you should not run into blocking problems.

import os
import subprocess

executable = "/home/pi/pi_sensors-master/bin/Release/i2c.exe"
proc = subprocess.Popen(['mono', executable])

try:
    outs, errs = proc.communicate(timeout=15) # Times out after 15 seconds.
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

Or you can call the communicate in a loop if you want a 'data-stream' of sort, an answer from this question:

from subprocess import Popen, PIPE

executable = "/home/pi/pi_sensors-master/bin/Release/i2c.exe"
p = Popen(["mono", executable], stdout=PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    print line,
p.communicate() # close p.stdout, wait for the subprocess to exit
Community
  • 1
  • 1
msvalkon
  • 10,851
  • 2
  • 37
  • 37
  • I tried it, but unfortunately nothing is being output – Hamoudy Jun 30 '14 at 12:14
  • I have no idea what `mono` is doing, but if it's some sort of a service which does not exit, then I assume `check_output()` will block. – msvalkon Jun 30 '14 at 12:18
  • yes it does not exit it keeps outputting stuff, is it possible to take a stream of this output as a constantly changing variable?\ – Hamoudy Jun 30 '14 at 12:21
  • 1
    @Hamoudy check my edit. You should be able to achieve what you want with `subprocess.Popen`. – msvalkon Jun 30 '14 at 12:27
  • it is strange that when I run the data stream, i get the first three lines and then stops: http://prntscr.com/3xy8sg – Hamoudy Jun 30 '14 at 12:32
  • do you think the buffer might be full? – Hamoudy Jun 30 '14 at 12:32
  • Yeah `communicate()` expects an EOF and you're apparently streaming data. I've edited the answer again, see if that works. I also found another question similar to yours from which I adapted the example. – msvalkon Jun 30 '14 at 12:41
  • Thanks a lot for your help btw – Hamoudy Jun 30 '14 at 12:44
  • Then you'll have to investigate further, the data stream is probably not what I expect. Try looking at the other answers in the question I linked. – msvalkon Jun 30 '14 at 12:45
  • I restarted my pi and it just worked, is it possible to remove the new line? – Hamoudy Jun 30 '14 at 12:58
  • Yeah, just add a comma after the print statement in the loop. Edited in the example now. `print line,` – msvalkon Jun 30 '14 at 13:40