Можете ли вы открыть stdin как файл на MS Windows в Python? - PullRequest
4 голосов
/ 22 января 2012

В Linux я использую supbprocess.Popen для запуска приложения. Командная строка этого приложения требует путь к входному файлу. Я узнал, что могу передать путь / dev / stdin в командную строку, а затем использовать Python subproc.stdin.write () для отправки ввода в подпроцесс.

import subprocess
kw['shell'] = False
kw['executable'] = '/path/to/myapp'
kw['stdin'] = subprocess.PIPE
kw['stdout'] = subprocess.PIPE
kw['stderr'] = subprocess.PIPE
subproc = subprocess.Popen(['','-i','/dev/stdin'],**kw)
inbuff = [u'my lines',u'of text',u'to process',u'go here']
outbuff = []
conditionbuff = []

def processdata(inbuff,outbuff,conditionbuff):
    for i,line in enumerate(inbuff):
        subproc.stdin.write('%s\n'%(line.encode('utf-8').strip()))
        line = subproc.stdout.readline().strip().decode('utf-8')
        if 'condition' in line:
            conditionbuff.append(line)
        else:
            outbuff.append(line)

processdata(inbuff,outbuff,conditionbuff)

Существует также версия этого приложения для MS Windows. Есть ли в MS Windows эквивалент использования / dev / stdin или это решение для Linux (Posix)?

Ответы [ 4 ]

2 голосов
/ 22 января 2012

Если myapp обрабатывает - как специальное имя файла, обозначающее stdin, то:

from subprocess import PIPE, Popen

p = Popen(['/path/to/myapp', '-i', '-'], stdin=PIPE, stdout=PIPE)
stdout, _ = p.communicate('\n'.join(inbuff).encode('utf-8'))
outbuff = stdout.decode('utf-8').splitlines()

Если вы не можете передать -, вы можете использовать временный файл:

import os
import tempfile

with tempfile.NamedTemporaryFile(delete=False) as f:
     f.write('\n'.join(inbuff).encode('utf-8'))

p = Popen(['/path/to/myapp', '-i', f.name], stdout=PIPE)
outbuff, conditionbuff = [], []
for line in iter(p.stdout.readline, ''):
    line = line.strip().decode('utf-8')
    if 'condition' in line:
        conditionbuff.append(line)
    else:
        outbuff.append(line)
p.stdout.close()
p.wait()
os.remove(f.name) #XXX add try/finally for proper cleanup

Для подавления stderr вы можете передать open(os.devnull, 'wb') как stderr в Popen.

2 голосов
/ 22 января 2012

Вы не должны использовать '/dev/stdin', но sys.stdin

1 голос
/ 22 января 2012

Общее количество снимков в темноте, но con: - это название консольного устройства (вы знаете, добрый старый copy con newfile.txt из DOS). Возможно, вы сможете передать con: в качестве аргумента программе, которая не будет принимать '-'.

0 голосов
/ 24 декабря 2012

Пожалуйста, используйте

import sys

sys.stdout.write ( "Abc \ N123 \ п")

или

для строки в sys.stdin.readlines ():

... печать строки

например

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...