2016-12-02 9 views
0

Я пишу скрипт-оболочку для программы, которая может принимать входные данные от STDIN. Мой скрипт должен обрабатывать каждую строку файла, но ему также необходимо перенаправить STDIN в программу, которую она обертывает. В минималистской форме, это выглядит примерно так:Чтение из stdin И пересылка его в подпроцесс в Python

import subprocess 
import sys 

for line in sys.stdin: 
    # Do something with each line 
    pass 

subprocess.call(['cat']) 

Обратите внимание, что я на самом деле не пытаюсь обернуть cat, он просто служит в качестве примера для демонстрации того или нет STDIN в пересылаются правильно.

В приведенном выше примере, если я прокомментирую цикл for, он работает правильно. Но если я запустил его с помощью цикла for, ничего не будет перенаправлено, потому что я уже прочитал до конца STDIN. Я не могу seek(0) в начале файла, потому что вы не можете искать в потоках.

Одно из возможных решений, чтобы прочитать весь файл в память:

import subprocess 
import sys 

lines = sys.stdin.readlines() 
for line in lines: 
    # Do something with each line 
    pass 

p = subprocess.Popen(['cat'], stdin=subprocess.PIPE) 
p.communicate(''.join(lines)) 

, который работает, но не очень память эффективно. Может ли кто-нибудь подумать о лучшем решении? Возможно, способ разделить или скопировать поток?

Дополнительные ограничения:

  1. Подпроцесс можно назвать только один раз. Поэтому я не могу читать строку за раз, обрабатывать ее и пересылать ее подпроцессу.
  2. Решение должно работать в Python 2.6
+0

Если я понимаю правильно, вы хотите, чтобы по существу вперед данные из 'stdin' в' stdin' подпроцесса? – bkvaluemeal

+0

Да, но если все, что я хотел сделать, это переслать 'stdin' в подпроцесс,' subprocess.call (['cat']) 'будет все, что мне нужно. Я хочу переслать 'stdin' и иметь возможность читать и обрабатывать его. –

ответ

0

ли эта работа для вас?

#!/usr/bin/env python2 
import subprocess 
import sys 

p = subprocess.Popen(['cat'], stdin = subprocess.PIPE) 

line = sys.stdin.readline() 

#################### 
# Insert work here # 
#################### 

line = line.upper() 

#################### 

p.communicate(line) 

Пример:

$ echo "hello world" | ./wrapper.py 
HELLO WORLD 
+0

Существуют две проблемы с этим решением: 1. Он только переводит первую строку stdin, а не каждую строку. Вам нужно будет использовать 'readlines' (множественное число) и присоединяться к ним при передаче их в подпроцесс. 2. Это то же самое решение, которое я уже представил, немного перепутал. У этого есть недостаток, что он считывает весь файл в память. Я ищу более эффективное решение для памяти (если оно существует). –

+0

Мысли здесь громко. Что делать, если код после подпроцесса находился внутри цикла while, непрерывно читающего в одной строке, обрабатывая его, а затем обменивая его? Разве это не будет похожим на то, что вы ищете? – bkvaluemeal

+0

См. Дополнительные ограничения: # 1. –

 Смежные вопросы

  • Нет связанных вопросов^_^