stty를 사용하여 tty를 올바르게 복원하세요.

stty를 사용하여 tty를 올바르게 복원하세요.

나는 일부 사용자 입력(예: 비밀번호 요청)을 읽기 위해 bash 스크립트를 작성 중이며 결과를 캡처하여 표준 출력을 통해 전달하려고 합니다. (저는 최신 소프트웨어를 사용하여 GNU/Linux 환경에서 작업하고 있습니다.)

다음은 문제를 재현하는 간단한 버전의 스크립트입니다.

....

# read_input.sh
#
# Issue B : redirection of "3>&1" here causes stty error when                                             
# this script is executed via a command subsitution context subshell                                                                       
exec 3>&1 </dev/tty >/dev/tty                                                                                     

tty_settings=`stty -g`                                                                                            

# Issue A : uncommented version doesn't restore tty properly.                                                     
#trap 'stty "$tty_settings";' EXIT                                                                                
#trap 'echo "...interrupting"; exit 1' INT ABRT HUP QUIT TERM                                                     
trap 'echo "...interrupting"; stty "$tty_settings"; exit 1' INT ABRT HUP QUIT TERM                                

stty -echo                                                                                                        

echo "Enter input: "                                                                                              
input=""                                                                                                          
while IFS= read -r -n1 char; do                                                                                   
    # nb: stripped out proper char handling code here,                                                            
    # (except return), for simplicity                                                                             
    if [[ $char = "" ]]; then                                                                                     
        break
    fi
    input+=$char
    echo -n "*"
done
echo ""

stty "$tty_settings"

#trap - EXIT INT ABRT HUP QUIT TERM
trap - INT ABRT HUP QUIT TERM

echo "$input" >&3

목적은 결과 입력을 fd 3(호출 시 이 스크립트의 stdout이 파이프에 연결된 경우)에 기록하는 동시에 상호 작용 중에 tty를 유지하는 것입니다. 그런 다음 stty를 사용하여 tty를 수정하여 에코 등을 제어하고 트랩 처리를 통해 모든 수정 사항을 되돌립니다.

두 가지 문제에 직면했습니다.


질문 A

제어 터미널로 돌아온 후에는 에코가 억제됩니다. 주석 처리되지 않은 활성 한 줄 핸들러 케이스 대신 두 줄 트랩 핸들러 케이스(주석 처리됨)를 사용해야 합니다.

한 줄의 경우 - INT라고 말하면 tty를 복원한 다음 핸들러를 통해 종료를 호출합니다. EXIT 자체를 캡처하는 것이 아닙니다. 왜 이 작업을 수행해야 합니까?


질문 B

이는 서브셸 컨텍스트에서 exec의 "3>&1" 리디렉션과 관련이 있습니다.

어떤 이유에서인지 서브셸에서 이 스크립트("read_input.sh")를 실행하고 명령 대체를 통해 다른 스크립트에서 출력을 가져오고 싶다고 가정해 보겠습니다.

....

# read_input_caller.sh
input=$(sh read_input.sh)
echo "$input"

호출 스크립트를 중단할 때 트랩 핸들러의 stty 호출이 다음(^C로 표시됨)을 불평하는 것을 발견했습니다.

stty: '표준 입력': 입력/출력 오류

이 오류 메시지는 exec 라인의 "3>&1" 리디렉션으로 인해 발생합니다. "3>&1" 없이 exec 라인을 호출하면 stty 오류가 없습니다(그러나 입력을 stdout에 전달하는 데는 그다지 유용하지 않습니다). 왜 이런 일이 발생하는지 알 수 없나요?

호출 스크립트에서 다른 하위 쉘은 다음과 같이 호출합니다.

....

sh read_input.sh | cat

이 오류는 생성되지 않습니다.

흥미롭게도 문제 B가 발생하면 문제 A의 문제 캡처/복구에도 불구하고 터미널을 제어하는 ​​tty가 올바르게 복원되는 것으로 보입니다.

관련 정보