Я пытаюсь создать процесс, чтобы я мог сделать следующее:
Отправить текст на его стандартный ввод и указать EOF, закрыв канал stdin.
Подключите стандартный вывод и стандартный поток процесса к устройству TTY, чтобы его поведение было идентично тому, когда он запускается внутри TTY.
Изначально я запустил процесс в pty с помощью creack/pty в Go, но вскоре понял, что нет способа «отправить» EOF. Я знаю, что EOF не является ни сигналом, ни символом, поэтому его нельзя отправить.
Возьмем, к примеру, поведение выделения в grep. Я хочу, чтобы grep вёл себя так, как будто он запускается в TTY (без указания флага --color). Для этого я хочу, чтобы его stdou был подключен к устройству TTY, а не к каналу. Но в то же время я хочу отправить входные данные в grep с помощью канала, чтобы я мог закрыть канал и указать EOF для grep.
Изменить: мне удалось добиться этого на C, используя следующий фрагмент кода:
Я пытаюсь создать процесс, чтобы я мог сделать следующее: [list] [*]Отправить текст на его стандартный ввод и указать EOF, закрыв канал stdin.
[*]Подключите стандартный вывод и стандартный поток процесса к устройству TTY, чтобы его поведение было идентично тому, когда он запускается внутри TTY.
[/list] Изначально я запустил процесс в pty с помощью creack/pty в Go, но вскоре понял, что нет способа «отправить» EOF. Я знаю, что EOF не является ни сигналом, ни символом, поэтому его нельзя отправить. Возьмем, к примеру, поведение выделения в grep. Я хочу, чтобы grep вёл себя так, как будто он запускается в TTY (без указания флага --color). Для этого я хочу, чтобы его stdou был подключен к устройству TTY, а не к каналу. Но в то же время я хочу отправить входные данные в grep с помощью канала, чтобы я мог закрыть канал и указать EOF для grep. [img]https://i.sstatic.net/zqh11Q5n.png[/img]
[b]Изменить[/b]: мне удалось добиться этого на C, используя следующий фрагмент кода: [code]#define _XOPEN_SOURCE 600 #include #include #include #include #include #include #include
int main() { int pipe_fd[2]; int master_fd, slave_fd; pid_t pid;
// Create pipe for stdin if (pipe(pipe_fd) == -1) { perror("pipe"); exit(1); }
// Create PTY for stdout/stderr // This makes grep think it's running in a terminal, enabling color output if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) { perror("openpty"); exit(1); }
pid = fork();
if (pid == -1) { perror("fork"); exit(1); }
if (pid == 0) { // Child process
// Close unused pipe end (write end) close(pipe_fd[1]);
// Redirect stdin to pipe read end dup2(pipe_fd[0], STDIN_FILENO); close(pipe_fd[0]);
// Close master PTY (parent uses this) close(master_fd);
// Redirect stdout and stderr to slave PTY dup2(slave_fd, STDOUT_FILENO); dup2(slave_fd, STDERR_FILENO); close(slave_fd);
// Execute grep with -P flag for Perl regex execlp("grep", "grep", "--color=auto" , "-P", "hello", NULL);
// If exec fails perror("execlp"); exit(1); } else { // Parent process
// Close unused pipe end (read end) close(pipe_fd[0]);
// Close slave PTY (child uses this) close(slave_fd);