{}가 Terminal.app에 äå로 표시되기 시작하는 이유는 무엇인가요?

{}가 Terminal.app에 äå로 표시되기 시작하는 이유는 무엇인가요?

CentOS 7.9를 실행 중인데 오늘 터미널에 이상한 문자가 표시됩니다. 일부 문자는 괜찮아 보이지만 일부 기호는 영어가 아닌 문자로 나타납니다. 예를 들어 다음 내용으로 텍스트 파일을 만들었습니다.

!@#$%^&*()_+{}

열어보니 위에 쓴거랑 똑같네요 vi. nano하지만 터미널에서는 다음과 같이 보입니다.

$ cat chars.txt 
!É#$%Ü&*()_+äå

$ od -An -vtx1 < chars.txt
 21 40 23 24 25 5e 26 2a 28 29 5f 2b 7b 7d 0a

이 이상한 문자는 내가 입력하는 동안에도 어디에나 있습니다. 그 기계는 오늘날까지도 훌륭하게 작동합니다. 나생각하다바이너리를 다운로드 curl하고 매개변수를 사용하는 것을 잊어버린 후에 이런 일이 일어났습니다 -O. 다른 사용자로 다시 시작하고 로그인해도 도움이 되지 않았습니다. 내 로케일 설정은 다음과 같습니다. 무엇을 더 찾아야 할지 모르겠습니다. 제가 사용하고 있는 쉘은 Bash 버전 4.2이며 특이한 점은 없습니다.

$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

편집: 서버의 쉘이 bash 4.2라고 말하는 것이 더 정확합니다. 저는 Terminal.app을 사용하여 macOS Big Sur에 로그인하고 있습니다.

답변1

이렇게 하면 xterm터미널 에뮬레이터(버전 366)를 사용하여 재현할 수 있습니다.

$ printf '\e[?42h\e(H'; cat chars.txt; printf '\e(B\e[?42l'
!É#$%Ü&*()_+äå

어디:

다른 사람들은 설정을 취소합니다.

터미널을 정상 상태로 복원하려면 ncurses 명령을 사용할 수도 있습니다 reset. 여기서 나는 \ec그것이 전송하는 시퀀스를 발견했습니다(예: rs1전송된 / 함수는 기본 문자 세트를 복원하는 역할을 담당합니다).reset_1stringtput rs1

정상적으로 표시되는 이유는 명령 세션에서 실행하고 나중에 결과를 보면 명령 세션으로 전환한 후 실제로 시퀀스가 ​​전송되는 nano것을 알 수 있습니다 (G0의 경우 US-ASCII 선택).nanoscripttypescriptnano\e(B대체 화면아마도 \e[?1049h일부 ncurses 초기화의 일부로 nano대체 화면에서 나갈 때 원래 문자 세트가 복원될 것입니다.

이제는 \e(H실수로 바이너리 파일에서 시퀀스(0x1b 0x28 0x48 바이트 시퀀스)를 얻는 것이 합리적입니다. 평균적으로 1,600만 개의 무작위 3바이트 시퀀스 중 하나는 이와 같습니다. 여기에서 몇 가지를 찾았습니다.

$ LC_ALL=C grep -rFl $'\e(H' /lib
/lib/x86_64-linux-gnu/libicui18n.so.66.1
/lib/x86_64-linux-gnu/ceph/libceph-common.so.2
[...]

예를 들어.

그러나 \e[?42h6바이트(48비트) 시퀀스가 ​​우연히 발견될 가능성은 훨씬 적습니다(280조 6바이트 시퀀스 중 1개). 게다가 \e(H터미널에 덤프한 임의의 바이너리에 이 두 파일을 순서대로 보관하세요.

하지만 xtermCentOS7에서는 이전 버전(295)입니다. 이번 릴리스에서는 \e[?42hISO2022 처리를 위해 시퀀스를 활성화할 필요가 없습니다. 이 버전에서는 xterm, \e(H, 하나만으로 동작을 얻을 수 있습니다. 그게 바뀌었어버전 297에서는2013년 9월 출시. 이는 최신 시스템보다 CentOS7 또는 해당 시대의 모든 시스템에서 이러한 현상이 발생할 가능성이 더 높은 이유를 설명합니다.

지적하신 대로 워크스테이션은 CentOS가 아닌 macos를 실행하고 있습니다. macos는 이전 버전의 xterm(2692021년 기준Terminal.app), 실제로 사용하고 있는 터미널 에뮬레이터 에 이전과 동일한 버그가 있다는 점을 분명히 해주시기 바랍니다. .xtermxterm

옛날에는 (지금까지xterm 182나는 그것이 변경되었다고 생각합니다), 바이너리를 터미널에 덤프할 때 또 다른 일반적인 문제는 다음으로 전환하는 것입니다.특수문자와 선화 세트0x0e 바이트( SO/ ^N제어 문자)가 터미널로 전송되는 경우. SO여전히 G1 세트로 전환되지만 G1 세트는 다음으로 초기화됩니다.선화 세트. 오늘은 시퀀스를 전송하여( \e(0선택선화 세트G0의 경우:

$ printf '\e(0 blahblah \e(B\n'
 ␉┌▒␤␉┌▒␤

ASCII에서 ^N/를 사용하는 원래 동작으로 돌아갈 수 있습니다 .^O선화 세트주문 으로 \e)0.

다시 시작해도 도움이 되지 않는 이유는 이스케이프 시퀀스의 영향을 받는 것이 터미널 에뮬레이터라는 점을 기억하세요. 터미널 에뮬레이터에서 입력한 시스템을 다시 시작해도 ssh도움이 되지 않습니다. 실행 중인 시스템을 다시 시작하면 xterm도움이 되지만 해당 터미널 에뮬레이터를 다시 시작하거나 reset위에 표시된 명령을 터미널에서 실행할 수도 있습니다( 이스케이프 시퀀스를 터미널 에뮬레이터에 보내는 ssh경우 로컬로 또는 를 통해).rs1

자세한 내용은 다음을 방문하십시오.

관련 정보