Reputation: 5974
I have a command ./rancli -c -
I enter in a shell that has this documentation:
Running the tool from the Linux shell allows additional options, depending on the options given to the command. The options are as follows:
-h Displays help about the command
-c Instead of taking typed commands interactively from a user the commands are read from the named file, i.e. in batch mode. When all commands are processed the CLI session ends automatically.
-c - As above but reads command from Linux stdin. This allows commands to be ‘piped’ to the program.
I wnat to convert this into python. If I use the second option everything works fine and it reads commands froma file and displays the results on screen. However I want to use the third option which writes to stdin. I would have thought this line would run a command ./rancli -c - commandHere
but it does not. What I have to do is enter ./rancli -c -
then I can write manually to stdin on the next line, such as here I use the command read hnb
:
[root@switch]# ./rancli -c -
read hnb
RAN> read hnb
HNBId Location RegUEs ActUEs
[email protected] n/c
[email protected] n/c
When i enter this in the shell I get the result printed out fine. However when i do it in my python I do not get the results printed back to me correctly. Here is what I tried:
ran_opt_get_ap = "read hnb\n"
cmd_rancli = ["/jffs2/usbflash0/ran/rancli", "-c", "-"]
proc = subprocess.Popen(cmd_rancli + [ran_opt_get_ap], stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ''):
print line,
proc.wait()
So when i pass in a command like that it obviously doesnt work like in the shell and is ignored. Now two issues here, How do I write the command to stdin here, seeing as I had to type the following command read hnb
manually? After I run rancli -c -
I want to then inject commands after, I have to type it in like so at the moment:
read hnb
RAN> read hnb
The other issue is that my code did not print out the full results above but when I type in the next command I get the rest of the results and the first line of next result and so on with every command, getting the results after I type the next command:
get ap
HNBId Location RegUEs ActUEs
[email protected] n/c
[email protected] n/c
RAN> get ap
Update: latest code works
cmd_rancli = ["/jffs2/usbflash0/ran/rancli", "-c", "-"]
ran_opt_get_ap = "read hnb"
proc = subprocess.Popen(cmd_rancli, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = proc.communicate(ran_opt_get_ap)[0]
print output
Upvotes: 2
Views: 976
Reputation: 414129
To write to subprocess' stdin, set it to PIPE:
from subprocess import Popen, PIPE
p = Popen(cmd_rancli, stdin=PIPE, stdout=PIPE)
output = p.communicate(ran_opt_get_ap)[0]
.communicate()
writes ran_opt_get_ap
to the subprocess' stdin, reads all output, and waits for the child process to finish.
The second issue is due to buffering (it only matters if you're not reading all output at once). To fix buffering:
sys.stdout.flush()
after you print somethingbufsize
parameter to zeropexpect
, pty
modules or stdbuf
, unbuffer
, script
commands.Upvotes: 4