我需要直接与通过stdin
生成的进程的stdout
和subprocess
进行交互。我可以做到:
proc = subprocess.Popen("/bin/bash", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
proc.stdin.write(b"whoami\n")
print(proc.stdout.readline())
但是,一旦进程分叉,我就无法与其进行交互。我有这个测试程序:
// child.c
#include <unistd.h>
int main() {
execve("/bin/bash", NULL, NULL);
}
我编译时使用的:
gcc -o child child.c
,当我在child
调用中使用/bin/bash
而不是Popen
尝试上述python代码时,出现broken pipe
错误。
我尝试过的:
由于默认情况下,由python创建的文件描述符是不可继承的,因此我尝试更改它:
inr, inw = os.pipe()
outr, outw = os.pipe()
os.set_inheritable(inr, True)
os.set_inheritable(inw, True)
os.set_inheritable(outr, True)
os.set_inheritable(outw, True)
proc = subprocess.Popen("./child", stdin=inr, stdout=outw, stderr=outw)
proc.stdin.write(b"whoami\n")
print(proc.stdout.readline())
os.close(inr)
os.close(inw)
os.close(outr)
os.close(outw)
但是我仍然遇到相同的错误。我认为这应该是一件容易的事,而且我可能会缺少一些东西。感谢您的帮助。
[EDIT]在编辑帖子之前,我使用test
代替child
作为测试c
可执行文件的名称。我了解到它确实是我的PATH中位于/usr/bin/test
上的程序。
将可执行文件名称更改为child
成功解决了我的问题。经过数小时的尝试和错误,我知道答案将变得如此简单...
非常感谢Barmar指出这一点!
答案 0 :(得分:1)
调用test
时,您调用的是/bin/test
,而不是程序。
要么重命名C程序,使其不与标准命令冲突,要么使用路径名访问它,从而不会搜索$PATH
。
proc = subprocess.Popen("./test", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)