在MS Windows上可以在Python中将stdin作为文件打开吗?

5 投票
2 回答
2417 浏览
提问于 2025-04-17 10:49

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

这个应用程序在Windows系统上也有一个版本。请问在Windows上有没有类似于/dev/stdin的东西,还是说这是Linux(Posix)特有的解决方案呢?

2 个回答

1

这句话有点像是在猜测,但这里提到的 con: 是控制台设备的名字(你知道的,就是老式的 DOS 命令 copy con newfile.txt)。你可能可以把 con: 作为参数传给那个不接受 '-' 的程序。

2

如果 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

撰写回答