2013-04-11 2 views
2

У меня есть команда ./rancli -c - я вхожу в оболочке, которая имеет эту документацию:запись на стандартный ввод, а также распечатка результатов правильно

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.

Я wnat, чтобы преобразовать это в питон. Если я использую второй вариант, все работает отлично, и он считывает команды из файла и отображает результаты на экране. Однако я хочу использовать третий вариант, который записывает в stdin. Я бы подумал, что эта строка будет запускать команду ./rancli -c - commandHere, но это не так. Что я должен сделать, это ввести ./rancli -c - то я могу написать вручную стандартного ввода на следующей строке, например, здесь я использую команду read hnb:

[[email protected]]# ./rancli -c - 
read hnb 
RAN> read hnb 
       HNBId       Location  RegUEs ActUEs 
    [email protected]     n/c 
    [email protected]     n/c 

Когда я вхожу это в оболочке я получаю результат распечатанный штраф , Однако, когда я делаю это на своем питоне, я не верну мне вернувшиеся результаты. Вот то, что я пробовал:

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() 

Так что, когда я прохожу в команде, как, что, очевидно, не работает, как в оболочке и игнорируется. Теперь два вопроса здесь. Как написать команду на stdin здесь, увидев, как мне пришлось вводить следующую команду read hnb вручную? После того, как я бегу rancli -c - я хочу затем вводить команды после того, как я должен ввести его в как и на данный момент:

read hnb                   
RAN> read hnb     

Другой вопрос в том, что мой код не печатать полные результаты выше, но когда я печатаю в следующей команде я получить остальную часть результатов и первую строку следующего результата и так далее с каждой командой, получать результаты после того, как я ввожу следующую команду:

get ap                   
       HNBId       Location  RegUEs ActUEs  
    [email protected]     n/c       
    [email protected]     n/c       
RAN> get ap 

Обновление: последний код работает

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 
+0

drop '[ran_opt_get_ap]' in 'Popen()' call, add ** 'stdin = PIPE' ** как в моем ответе. 'bufsize = 0' не нужно, если вы используете' .communicate() ', но здесь тоже не должно быть. – jfs

+0

Спасибо, я сделал, как вы сказали, с трубой, и это сработало. Просто нужно было удалить \ r \ n. – Paul

+0

@ J.F.Sebastian Я выставил последний код, и он работает, спасибо большое. – Paul

ответ

4

Чтобы написать подпроцесс стандартного ввода, установите его ТРУБЫ:

from subprocess import Popen, PIPE 

p = Popen(cmd_rancli, stdin=PIPE, stdout=PIPE) 
output = p.communicate(ran_opt_get_ap)[0] 

.communicate() пишет ran_opt_get_ap в подпроцесс стандартного ввода, считывает все выходные, и ожидает процесса завершения дочернего.

Вторая проблема связана с буферизацией (это имеет значение только в том случае, если вы не читаете весь вывод сразу). Чтобы исправить буферизацию:

  • выхода вашей программы, добавьте sys.stdout.flush() после печати что-то
  • трубы на вашем конце, установите bufsize параметр POPEN к нулю
  • подпроцесса, используйте pexpect, pty modules или stdbuf, unbuffer, script commands ,
+0

Спасибо, попробуем это, любая разница в выполнении этого для subprocess.PIPE или PIPE? stdin = subprocess.PIPE и т. д.? – Paul

+0

Пробовал ваше первое предложение: для строки в iter (proc.stdout.readline, ''): ValueError: операция ввода-вывода в закрытом файле – Paul

+0

Спасибо за все усилия. Если я поставлю sdtin = pipe, то я никогда не получу никаких результатов и не смогу даже выйти, придется перезагрузить устройство. Если я использую p.communicate (ran_opt_get_ap) [0], я никогда не получаю результатов, поскольку я предполагаю, что он ждет завершения процесса? В любом случае я даже не получаю код чтения. – Paul