I have compiled a windows executable that connects to a software radio and reads out the values in its registers. When I execute this in command prompt, it returns me the following output
My hardware is connected via USB to COM4, when I pass these as arguments, I get the following screen where I can choose between ranging to other radios with their ID's (100 is the Host Radio. 101, 102 103 and 104 are other radios) or can quit the application by typing 'q'.
If I input the ID of the radio to be ranged, I get the ranging information and this process continues until i quit by typing 'q'
Now, Im trying to write a python script where I can call this executable, get the values and store them for further processing. I have read in other topics that this can be achieved by the library 'subprocess'. My code snippet as follows
#!/usr/bin/env python
import subprocess
import time
#subprocess.Popen([r"C:\Users\Raja\Documents\SUMO_Final\rcmSampleApp.exe"])
p = subprocess.Popen("C:/Users/Raja/Documents/SUMO_Final/rcmSampleApp.exe -u COM4", shell = True, stdin = subprocess.PIPE)
p.stdin.write('104')
time.sleep(5)
p.stdin.write('q')
p.kill()
When I execute this in .py file, the .exe loops indefintely as shown below
Some answers in the forum suggest changing shell = False and terminate the process before killing it but it is not clear for me. Can someone please help?
Cheers
flush
the pipe when you write a command (and include newlines to simulate user inputs with Enter key presses, assuming program expects that), and close
the pipe when you're done. It's also generally a good idea to avoid shell=True
, as it introduces additional layers wrapping the command (and in circumstances other than this one, adds security and stability issues). Try:
#!/usr/bin/env python
import subprocess
import time
# Use list form of command to avoid shell=True, and raw string to allow
# safe use of "normal" looking Windows-style path
# Include universal_newlines=True automatic str decoding in Py3; it might
# fix newlines on Py2 as well, but if not, you'll need to explicitly send
# \r\n instead of just \n to match OS conventions (or use os.linesep to autoselect)
p = subprocess.Popen([r"C:\Users\Raja\Documents\SUMO_Final\rcmSampleApp.exe", "-u", "COM4"],
stdin=subprocess.PIPE, universal_newlines=True)
p.stdin.write('104\n') # Include newline that manual entry includes
p.stdin.flush() # Ensure write not buffered
time.sleep(5)
p.stdin.write('q\n') # Include newline
p.stdin.close() # Flush and close stdin, so program knows no more input coming
p.kill() # Depending on program, p.join() might be enough
Assuming p.join()
works, you could replace the last three lines ( write
, close
and kill
/ join
) with just:
p.communicate('q\n')
which will perform all three tasks implicitly.
When you use your program interactively, I assume that you type 101 Return , and then q Return .
When you start it from Python, you must simulate that Return with a \\n
, and you should wait the program to end instead of killing it:
p.stdin.write('104\n')
time.sleep(5)
p.stdin.write('q\n')
p.wait()
But as you only pass known output, if you just want to read and process the output you best choice is to use communicate
:
out, err = p.communicate('104\nq\n')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.