터미널을 되찾는 법

4 hours ago 3

less와 fzf는 파일이나 후보 목록을 stdin 파이프로 받으면서, 제어 터미널인 /dev/tty를 별도 파일 디스크립터로 열어 키보드 입력을 읽음 각 프로세스는 fd 0과 fd 1이 터미널인지 검사해 첫 단계·중간 단계·마지막 단계를 구분하므로 별도 단계 번호가 필요 없음 다운스트림 프로세스는 파이프가 잠시 비었을 때가 아니라 앞 단계의 쓰기 끝이 모두 닫혀 EOF가 발생할 때 깨어나며, 파이프 자체가 순차 실행의 인계 수단이 됨 터미널 입력은 브로드캐스트가 아닌 큐지만, 각 프로세스가 이전 파이프의 EOF를 기다린 뒤 /dev/tty를 읽기 때문에 동시 입력 경쟁을 피할 수 있음 /dev/tty는 호출 프로세스의 제어 터미널을 가리키며, 제어 터미널이 없는 헤드리스 환경이나 구체적인 pty 장치가 필요한 일부 macOS 프로그램에서는 그대로 사용할 수 없음 하나의 바이너리를 네 번 연결한 실험 같은 바이너리를 다음처럼 네 단계로 연결함 ./target/debug/feat-test | ./target/debug/feat-test | ./target/debug/feat-test | ./target/debug/feat-test 각 단계는 자기 차례에 터미널에서 한 줄을 읽고, 지금까지 축적된 줄과 각 줄을 읽은 프로세스의 PID를 다음 단계로 전달함 마지막 단계는 네 줄과 각각의 PID를 사용자에게 출력함 입력 전에 다른 창에서 ps를 실행하면 네 프로세스가 모두 존재함 셸은 앞 단계가 끝날 때까지 기다리지 않고 전체 파이프라인을 한꺼번에 실행함 마지막 프로세스도 키 입력 전부터 살아서 대기함 실험은 세 가지 문제를 확인함 같은 바이너리가 파이프라인에서 자기 위치를 알아내는 방법 fd 0이 파이프를 가리킬 때 키보드에 다시 접근하는 방법 처음부터 실행 중인 네 프로세스가 입력을 동시에 읽지 않는 이유 fd 0과 fd 1로 단계 판별하기 stdin과 stdout은 파이프라인 전체가 아니라 각 프로세스에 속함 셸은 각 프로세스의 fd 0과 fd 1을 서로 다른 대상으로 연결함 첫 프로세스의 fd 0은 터미널을 가리킴 이후 프로세스의 fd 0은 이전 단계의 파이프를 가리킴 마지막 프로세스의 fd 1은 터미널을 가리킴 앞선 프로세스들의 fd 1은 다음 단계로 이어지는 파이프를 가리킴 Rust의 IsTerminal로 연결 대상을 검사할 수 있음 stdin.is_terminal()이 참이면 첫 단계로 판단해 stdin에...

Read Entire Article