Следующие коды Python создают канал с os.pipe()
и передают свои файловые дескрипторы подпроцессу через pass_fds
из subprocess.Popen()
. stdout
, stderr
, а код возврата ведет себя как ожидалось. Однако попытка прочитать канал с os.fdopen()
после завершения подпроцесса ничего не даст; программа не завершается, потому что read()
постоянно ожидает, что что-то будет записано в канал.
import subprocess as sp
import os
r, w = os.pipe()
p = sp.Popen(
["fd_test", str(w)],
text=True,
stdout=sp.PIPE,
stderr=sp.PIPE,
pass_fds=(r, w)
)
stdout, stderr = p.communicate()
print(stdout)
print(stderr)
print(p.returncode)
with os.fdopen(r, "r") as msg:
print(msg.read())
Подпроцесс, fd_test
, представляет собой короткую программу, написанную мной на C ++, которая пишет "Hello, world!" к данному дескриптору файла:
#include <cstdio>
#include <string>
#include <unistd.h>
int main(int argc, char* argv[]) {
if (argc < 2)
return 1;
int fd = std::stoi(std::string(argv[1]));
std::string msg = "Hello, world!\n";
if (write(fd, msg.c_str(), msg.size()) == -1) {
std::fprintf(stderr, "Failed to write to '%d'\n", fd);
return 1;
}
/*char* buf[512] = {0};
if (read(fd - 1, buf, 512) == -1 {
std::fprintf(stderr, "Failed to read from %d'\n", fd - 1);
return 1;
}
std::printf("%s", buf);*/
std::printf("Wrote message to %d\n", fd);
std::fprintf(stderr, "No errors, hurray!\n");
}
Программа не сообщает об ошибках записи в дескриптор файла. Фактически, закомментированный код может успешно читать только что написанное, а родительский процесс Python - нет.
Как я могу это исправить? Единственное, о чем я мог подумать, это os.set_inheritable()
, но это не помогло.