Мне нужно напрямую взаимодействовать с 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
и когда я пытаюсь использовать приведенный выше код Python с child
вместо /bin/bash
в Popen
вызов, я получаю 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 за то, что указал на это!