^D/EOT 문자를 쉘 프로세스의 표준 입력으로 어떻게 보내나요?

^D/EOT 문자를 쉘 프로세스의 표준 입력으로 어떻게 보내나요?

하나는 PID 1234이고 다른 하나는 PID 5678인 두 개의 쉘을 연다고 가정합니다.

저 할 수 있어요화면 지우기터미널 자체의 프롬프트에 입력하는 echo $'\033c' > /proc/1234/fd/0것처럼 다른 쉘을 재설정합니다 . reset그러나 echo $'\04' > /proc/1234/fd/0EOT 문자를 보낼 때는 작동하지 않는 것 같습니다. 원하는 효과를 어떻게 얻을 수 있습니까?

답변1

첫째, tty는 비록 파일 객체처럼 보이지만 실제로는 한 쌍의 파이프/큐입니다. 하나는 출력용이고 다른 하나는 입력용이며, 각 파이프/큐의 다른 쪽 끝은 일부 하드웨어 장치에 연결되어 있습니다. 의사 터미널의 경우 다른 프로그램에서 사용됩니다. tty에 연결된 fd에 무엇이든 쓸 때, 여러분은 쓰고 있는 것입니다.산출큐(프로세스의 fd 0(stdin)인 경우에도 루프백하지 않음)입력하다대기줄.

대부분의 Unix 시스템에서 (주목할만한 가치가 있습니다.오픈BSDTIOCSTI), 마치 상대방으로부터 받은 것처럼 tty의 입력 큐에 바이트를 삽입할 수 있게 해주는 특별한 ioctl()이 있습니다 . TIOCSTI이를 호출하는 프로세스의 제어 tty에 사용되지 않은 경우 루트로만 작동합니다.

$ cc -Wall tiocsti.c -o tiocsti

-- 루트 사용자로 --

# printf '\04' | ./tiocsti >/proc/5460/fd/0

프로세스가 pseudo-tty에서 실행 중인 경우 입력을 "가짜"로 만드는 또 다른 방법은 디버거를 사용하여 pseudo-tty의 마스터 측을 보유하는 프로세스에 연결하고 write(2)거기에서 해당 프로세스에 내용을 넣는 것입니다.

$ gdb -p pid_of_xterm
(gdb) p write(4, "\x04", 1)   # 4 is the fd of the master pty
(gdb) c

두 방법 모두 그냥지나침. 실행 중인 프로세스를 제어하려면 일부 입력을 위조하는 것보다 프로세스에 디버거를 연결하는 것이 좋습니다. 대화형 프로그램을 도구로 사용하려면 이를 실행하는 것이 좋습니다.expect;둘 다 모든 Unix 시스템에서 실행되며 추가 권한이 필요하지 않습니다.

또한 ^D/는 다음과 같은 경우 \004에만 작동합니다.EOFㅏ)tty가 표준 모드에 있습니다.두번째) c_cc[VEOF]특수문자는 다른 문자로 변경되지 않습니다.) 출력 큐는 비어 있습니다(그렇지 않으면 c_cc[VEOF]두 번 보내야 합니다). 물론 tty에서 읽는 프로세스는 EOF 또는 해당 바이트를 얻지만 반드시 쉘을 얻지는 않습니다.

tiocsti.c

#include <sys/ioctl.h>
#include <unistd.h>
#include <err.h>

int main(void){
        char c; ssize_t r;
        while((r = read(0, &c, 1)) > 0){
                if(ioctl(1, TIOCSTI, &c)) err(1, "ioctl(TIOCSTI)");
        }
        if(r < 0) err(1, "read");
        return 0;
}

관련 정보