为简化起见,我们假设shell脚本是cat
命令。在shell中,通常会这样调用:
$ cat /some/path/myfile.txt
现在,文件将动态创建并将其写入磁盘将成为主要的性能损失,存在安全问题并增加多用户环境中的文件管理开销。该脚本无法修改,也无法从标准输入读取(cat
只是一个工作样本)。
我试过了:
import os
pin, pout = os.pipe()
pin, pout = os.fdopen(pin, 'r'), os.fdopen(pout,'w')
from subprocess import Popen
pout.write("test")
pout.flush()
p = Popen('cat /proc/self/fd/%s' % pout.fileno(), shell=True)
即使我关闭pout
p.poll()
仍然没有返回任何显示该命令仍在等待来自管道的更多输入的内容。
如何告诉命令没有更多来自管道的数据? 还有其他方法可以解决这个问题吗?
修改
在bash中,如果文件内容是由名为prog1
的程序生成的,那么这将以这种方式解决:
$ cat <(prog1)
修改2
如果你不需要shell,那么Alfe提到的另一个选项更好,虽然问题仍然存在(即读取文件内容后进程没有完成)
#...same as before
p = Popen(['cat', '/dev/stdin'], stdin=pout)
答案 0 :(得分:1)
这是我最后所做的,但并不好。
因为我正在研究CentOS以及我遇到的问题(我在这里问了一下:Python Popen can't open bash shell in CentOS/Red Hat)我不能使用execute='/bin/bash'
这就是解决方案看起来有点不同的原因而不是问题。
我正在使用bash流程替换和here-documents:
将一些配置传递给流程file_contents = '...'
p = Popen(['/bin/bash', '-c', "cat <(cat<<'EOF_CFG'\n%s\nEOF_CFG\n)" % file_contents])
我现在正在考虑使用tmpfs在其上创建命名管道。我认为首先启动脚本然后写入管道应该可以工作......如果我成功了,我也会在这里写。
答案 1 :(得分:0)
摆弄一下,似乎关闭一侧的管道不会在关联的伪文件上生成eof / proc / self / fd /&lt;#&gt;儿童过程您是否尝试使用/ dev / stdin并简单地将输入传递给子进程的stdin?
答案 2 :(得分:0)
尝试使用命名管道。在它上面,EOF正确传播:
$ mkfifo bla
$ python
from subprocess import Popen
p = Popen('cat bla', shell=True)
with file('bla', 'w') as f:
f.write('test')
您也可以在Python中动态创建命名管道,当然,只需使用os.mkfifo()
。