학습TLDP의 고급 Bash 스크립팅 가이드Debian 9의 bash 4.4.12에서 tty 및 pts의 다음 셸 출력을 재구성할 수 없습니다:
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 363 bozo 0u CHR 136,1 3 /dev/pts/1
bash 363 bozo 1u CHR 136,1 3 /dev/pts/1
bash 363 bozo 2u CHR 136,1 3 /dev/pts/1
bash$ exec 2> /dev/null
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 371 bozo 0u CHR 136,1 3 /dev/pts/1
bash 371 bozo 1u CHR 136,1 3 /dev/pts/1
bash 371 bozo 2w CHR 1,3 120 /dev/null
두 번째 명령을 실행할 때마다 셸 프롬프트가 사라지고 모든 키보드 입력 표시가 중지되지만 여전히 명령을 실행하고 출력을 볼 수 있습니다. 왜 그런 겁니까?
답변1
이는 쉘의 표준 오류를 리디렉션했기 때문입니다.
표준에 따르면 POSIX 호환 쉘은 여기에 대화형 프롬프트를 작성해야 합니다.
이것본 패권,가보 본, (더반그리고FreeBSD)93 코헨,MirBSD 코헨, (FreeBSD, OpenBSD 및더반) 코헨 PD, (FreeBSD그리고더반) 알름퀴스트, 그리고와타나베쉘은 이를 준수하고 대화형 프롬프트를 표준 오류에 기록합니다. 당신은 그들 모두에서 시기적절한 행동이 부족하다는 것을 알게 될 것입니다.
그러나 입력을 에코하지 않는 동작은 더 복잡합니다.
- Debian PD Korn, Debian Almquist 및 Heirloom Bourne 쉘은 자체 라인 편집기를 구현하지 않지만 커널의 터미널 라인 규칙에서 제공하는 라인 편집기를 사용합니다. 입력이 표준 입력으로 에코되는 것을 계속 볼 수 있습니다.
- Watanabe, (FreeBSD 93) Korn 및 (Debian 93) Korn 쉘은 자체 라인 편집기를 구현합니다.반품편집 중인 입력 라인을 (재)표시할 때 표준 오류에 기록합니다. 그러나 터미널에 에코가 표시됩니다.존재하다명령을 실행하기 전
exec
및 (표준 오류는 더 이상 터미널 장치가 아니기 때문에)다시 닫지 못했습니다.다음 입력을 위해 라인 편집기가 호출될 때. 따라서 쉘 라인 편집기의 입력 에코가 이제 리디렉션된 표준 오류로 이동하더라도 터미널 라인 규칙에 의해 입력한 추가 입력을 볼 수 있습니다. 또한 라인 편집기는 추가 터미널 크기 변경을 인식하지 못하는 등 미묘한 방식으로 버그를 발생시킵니다. /dev/tty
MirBSD Korn, (FreeBSD PD) Korn 및 (OpenBSD PD) Korn 쉘은 편집된 행을 표준 오류에 (재)표시하지만 다른 파일 설명자를 직접 열어 터미널 에코 등의 내용을 제어하는 자체 행 편집기를 구현합니다 . 그들을성공다음 입력을 위해 라인 편집기를 호출할 때 에코를 다시 끄십시오. 이렇게 하면아니요입력할 때 줄 편집기에서 에코된 추가 입력 보기또는터미널 라인 규율.- Bourne Again 및 FreeBSD Almquist 쉘은 편집된 행을 표준 오류에 (재)표시할 수 있는 자체 행 편집기를 구현합니다.입력하다터미널 에코와 같은 것을 제어합니다. 그들을성공다음 입력을 위해 라인 편집기를 호출할 때 에코를 다시 끄십시오. 이렇게 하면아니요입력할 때 줄 편집기에서 에코된 추가 입력 보기또는터미널 라인 규율.
이것비지박스 알름퀴스트그리고지이와 관련하여 쉘은 POSIX와 호환되지 않습니다. 그들은 모두 자체 라인 편집기를 구현합니다. 이 두 가지를 모두 사용하면 이 부록에서 발생한다고 믿게 되는 동작을 볼 수 있습니다.
- BusyBox Almquist 쉘의 라인 편집기는 입력 에코에 표준 출력을 사용합니다.반품프롬프트를 쓰는 곳입니다. 표준 오류 리디렉션의 영향을 전혀 받지 않습니다. 그러나 표준 출력을 리디렉션하면 효과를 얻을 수 있습니다. 표준 입력을 사용하여 터미널 크기의 변화를 인식합니다.
- Z 셸은 ZLE를 실행할 터미널 장치를 찾으려고 노력합니다(명시적으로 열기까지 포함)
/dev/tty
. 시작 시 파일 설명자를 터미널 장치에 복사합니다. 그런 다음 ZLE는 이를 사용합니다.모든 것;입력된 입력을 에코하는 데 사용됩니다.읽다대화형 프롬프트를 작성하고 터미널 에코를 켜거나 끄기 위한 입력을 입력했습니다. 따라서 ZLE는 표준 오류, 출력 또는 입력의 후속 리디렉션에 영향을 받지 않습니다. 원하는 경우 세 가지 모두/dev/null
by 로 리디렉션할 수exec
있으며 Z 셸은 계속해서 대화형으로 메시지를 표시하고 입력을 받습니다.
(이것톰슨exec
쉘은 쉘 명령 메커니즘이 발명되기 이전부터 지원하지 않습니다. )
이 부록이 잘못되었다고 저자인 Stéphane Chazelas에게 불평해야 고칠 수 있습니다.
추가 읽기
- "쉘 변수". 셸 및 유틸리티. 기본 사양. IEEE 1003.1:2017. 그룹을 엽니다. 2017.
- https://unix.stackexchange.com/a/299440/5132