Paul
Paul

Reputation: 5974

writing to stdin and also printing out results correctly

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

Answers (1)

jfs
jfs

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:

Upvotes: 4

Related Questions