sh의 표준 입력으로 전송된 TTY 제어 문자는 효과가 없습니다.

sh의 표준 입력으로 전송된 TTY 제어 문자는 효과가 없습니다.

실행할 수 있는 원격 애플리케이션을 개발하려고 합니다.거기에서 들어오는 데이터를 다시 보내면서 일부 특수 시퀀스가 ​​작동하지 않는 것을 발견했습니다.

그래서 테스트 목적으로 데스크탑에서 부팅 sh한 다음 명령을 실행하고 다음으로 ping localhost다른 셸에서 실행하여 핑을 중단하려고 했습니다. 바이트는 echo -e "\003" > /proc/$shPID/fd/0+ 조합 0x3으로 생성된 바이트 입니다. 내가 무엇을 하려고 해도CtrlC(개행 추가, 시작 부분에 CSI 추가), 작동하지 않습니다. 문자가 표준 출력에 나타납니다. (예를 들어 개행 문자를 의미합니다), 그러나 ping 작업을 중단하지는 않습니다.

sh의 stdin을 통해 ping을 중단하는 방법은 무엇입니까?

답변1

^C 처리는 쉘이 아닌 터미널 장치 드라이버에 의해 수행됩니다.

이 문자가 tty 장치에 연결된 라인에서 수신되면(또는 의사 터미널 쌍의 마스터 측에 기록됨( 를 xterm누를 때 수행됨 Ctrl+C)) tty 라인 규칙(커널)이 터미널의 전경 프로세스 그룹에 씁니다. SIGINT 신호를 보냅니다.

따라서 해당 문자를 xterm이 콘솔에서 여는 fd로 보내야 합니다.

$ eval "$(xprop -notype -id $WINDOWID 32i '=$0\n' _NET_WM_PID)"; lsof -ap "$_NET_WM_PID" /dev/ptmx
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xterm   21123 stephane    4u   CHR    5,2      0t0 1460 /dev/ptmx

Linux에서 작성하면 /proc/21123/fd/4작동하지 않습니다. 다시 열리므로 /dev/ptmx동일한 의사 터미널을 참조하지 않기 때문입니다. 설득력이 필요해저것 xtermfd 4에 ^C를 씁니다.

그래서 그것은 실제로 선택 사항이 아닙니다.

자신만의 의사 터미널 쌍을 시작하고 그 안에서 sh 및 ping`을 실행할 수 있습니다. 그런 다음 마스터 측에 ^C를 작성하여 해당 SIGINT를 전경 프로세스 그룹으로 보낼 수 있지만 여기서는 신호를 직접 보내는 것이 더 쉽습니다(SIGTERM이 선호됨).

또한 에 문자를 쓰려고 시도하는 것은 /proc/$pid/fd/0실제로 의미가 없습니다. 파일 설명자는 일반적으로 읽기 위해 열려 있습니다. Linux에서 open()을 실행하면 실제로 /proc/$pid/fd/0fd가 가리키는 리소스가 다시 열립니다.

예를 들어 shwas가 로 시작하는 경우 sh < /some/file작업을 수행하면 echo something > "/proc/$shpid/fd/0"의 내용이 with로 대체됩니다. tty인 경우 해당 터미널에만 표시됩니다. 쓰기가 무언가를 읽는 유일한 경우는 sh stding이 파이프일 때입니다. Linux(및 Linux에만 해당)에서 쓰기 모드(파이프가 있는 경우)를 수행하면 파이프의 쓰기 쪽이 열립니다(그리고 fd 0은 실제로 읽기 쪽을 가리킵니다)./some/filesomething\nsomethingsomethingshopen()/proc/$shpid/fd/0

관련 정보