캐릭터들은 어디로 가는 걸까요?

캐릭터들은 어디로 가는 걸까요?

유효한 쉘 \u(bash +4.3, ksh93 또는 zsh)에서는 유니코드 문자를 인쇄할 수 있습니다.

$ printf 'a b c \ua0 \ua1 \ua2 \ua3 \n'
a b c   ¡ ¢ £

어느 것 출신인가라틴어-1_보충범위.

그러나 유니코드 문자가 추가되면 9f유니코드가 인쇄될 때까지 인쇄가 중지됩니다.9c

그리고 (APC와 ST) \u9f\u9cC1제어 문자.

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n'
a b c    ¡ ¢ £ 

캐릭터는 반드시 사라지게 됩니다.

확실히 printf모든 문자가 생성되고 터미널 대신 다른 소프트웨어로 출력을 리디렉션하면 생성된 문자가 표시됩니다.

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n' | od -A n -tx1
 61 20 62 20 63 20 c2 9f 20 64 20 65 20 66 20 c2
 9c 20 c2 a0 20 c2 a1 20 c2 a2 20 c2 a3 20 0a

이는 캐릭터가 생성되고 있다는 충분한 증거입니다. 그렇다면 왜 인쇄되지 않습니까(일부 눈에 띄는 문자 모양으로 표시됨)?

내 질문은 다음과 같습니다

  1. 실제로 .where APC에 연결됩니다 ST. 정의되어 있습니까?
  2. 이 둘 사이의 문자가 일부 응용 프로그램으로 전송됩니까?
  3. 그렇다면 어떤 응용 프로그램에 적용됩니까?
  4. 이 리디렉션에 대한 책임은 누구에게 있습니까? 쉘, 터미널 또는 다른 것?

편집하다

xterm터미널이나 터미널 모두 문자를 konsole제거 하지 않습니다.d e f

이는 쉘이 아닌 터미널 응용 프로그램의 내부 문제임을 확인합니다. 아직 정의된 위치를 찾지 못했습니다.

답변1

APC가 실제로 ST에 연결되어 있습니까? 어디에 정의되어 있나요?

이러한 제어 문자는 실제로 유니코드의 기본 문자는 아니지만 다음과 같은 이전 문자 세트 사양에서 상속됩니다.ECMA-48, ISO/IEC 6429 및 ISO/IEC-8859 문자 인코딩 시리즈. 광범위하게 말하자면, 이러한 표준은 기본적으로 C1 제어 문자에서 서로 일치합니다(서로 및 일부 이전 사양과도 이전 버전과 호환되기 때문입니다).

ISO/IEC 6429의 사본이 판매되기 때문에 인터넷에서 무료로 합법적인 사본을 찾을 수 있을 것으로 기대하지는 않지만 ECMA-48에서는 다음과 같이 말합니다.

8.3.2 APC - 응용 프로그램 명령

기호: (C1)

대표자: 09/15 또는 ESC 05/15

APC는 애플리케이션에서 사용되는 제어 문자열의 시작 구분 기호로 사용됩니다. 다음 명령 문자열은 00/08 ~ 00/13 및 02/00 ~ 07/14 범위의 비트 조합으로 구성될 수 있습니다. 제어 문자열은 종료 구분 기호 STRING TERMINATOR(ST)로 닫힙니다. 명령 문자열의 해석은 관련 애플리케이션에 따라 다릅니다.

그리고:

8.3.143 ST——문자열 종결자

기호: (C1)

대표자: 09/12 또는 ESC 05/12

ST는 APC(응용 프로그램 명령), DCS(장치 제어 문자열), OSC(운영 체제 명령), PM(개인 메시지) 또는 SOS(문자열 시작)에 의해 열리는 제어 문자열에 대한 끝 구분 기호로 사용됩니다.

유니코드는 C1 제어 문자 범위에서 하나의 제어 문자(U+0085 다음 줄(NEL))만 정의합니다. C1 범위에 있는 다른 문자의 경우,사양의 이 부분적용 가능:

제어 코드의 의미는 일반적으로 해당 코드가 사용되는 애플리케이션에 따라 결정됩니다. 그러나 특정 적용이 없는 경우 ISO/IEC 6429:1992에 지정된 제어 기능 의미에 따라 해석될 수 있습니다.

여기서는 확인할 수 없지만 위에서 언급한 것처럼 ISO/IEC 6429가 ECMA-48이 말하는 것과 매우 유사할 것으로 예상합니다. 또한 터미널 작성자는 "ECMA-48과 같은 유니코드 이전 7비트 및 8비트 문자 인코딩과의 역호환성"을 고려했을 수도 있습니다.특정 애플리케이션.

따라서 터미널은 APC와 ST 사이의 문자를 "이 문자의 목적은 모르지만 이 문자가 일반 출력으로 표시되도록 의도된 것은 아니다"라고 합법적으로 해석할 수 있습니다.

터미널은 특정 방식으로 반응하도록 프로그래밍되거나 프로그래밍되지 않을 수 있습니다.특정 문자열APC와 ST 사이를 래핑하고 일치하지 않는 문자열을 무시합니다. 터미널 창은 '인류 이전의 마지막 단계'이기 때문에 당연히 어떤 추측도 가능하다.응용 프로그램 명령여기에 도달하는 문자열은 터미널이 작업을 해석하고 수행하기 위한 것입니다(해당되는 경우). 터미널이 인식하지 못하는 문자열은 오류여야 합니다.

문자열이 "응용프로그램별 제어 문자열"로 유효하게 인코딩되었기 때문에 "잘못된 인코딩" 문자나 기타 오류 메시지를 표시하는 것은 부적절합니다.전시용이 아닌". 따라서 제목 질문 "캐릭터는 어디로 가고 있습니까?" "대답은 아마도 이렇습니다.잘못된 제어 문자열의 일부로 삭제됩니다..

그러나 유니코드 사양에는 "...가능한"..." 대신 "..."으로 해석됩니다.~ 해야 하다해석됨...". 따라서 다른 터미널 구현에서 적용 가능한 의미가 없는 인쇄할 수 없는 제어 문자로 APC 및 ST 문자를 무시하도록 선택하는 것이 반드시 유효하지 않은 것은 아닙니다.

스택 오버플로에 대한 이 질문APC 및 ST 제어 문자와 관련된 제어 순서도 설명합니다.

거기에 허용되는 답변은 다음과 같습니다.

현실은 APC가 거의 구현되지 않는다는 것입니다. 대부분의 시스템은 APC 시퀀스를 생성하지 않으며 수신된 시퀀스를 자동으로 무시합니다. 연결의 다른 쪽 끝이 구성 옵션을 통해 활성화하는 것과 같은 특정 방식으로 APC 시퀀스를 사용하고 있다는 것을 알지 못하는 한, 어떤 애플리케이션도 APC 시퀀스를 보내거나 해석해서는 안 됩니다. 터미널 에뮬레이터는 특정 의미를 할당합니다 [...]

답변2

이 문자는 어디에도 전송되지 않으며 전혀 전송되지 않습니다.보여주기 위해출력에 있지만 터미널을 통해 다음을 수행합니다.

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n' | od -c
0000000   a       b       c     302 237       d       e       f     302
0000020 234     302 240     302 241     302 242     302 243      \n
0000037

파일로 리디렉션한 다음 해당 파일을 조사하여 출력에 해당 항목이 있는지 확인할 수도 있습니다.

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n' > file
$ od -c file
0000000   a       b       c     302 237       d       e       f     302
0000020 234     302 240     302 241     302 242     302 243      \n
0000037

터미널이 구현 \u9f에 따라 조합하여 수행하는 작업처럼 보입니다 . \u9c그런 일이 일어난다당신의터미널은 몇 문자 뒤로 이동하고 거기에서 인쇄를 계속하여 이를 처리하므로 다른 문자를 덮어쓰게 됩니다. 이것이 바로 다음과 같은 이유입니다.

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n'
a b c    ¡ ¢ £ 

이것을 에서 재현할 수 있지만 gnome-terminator공백 xterm만 인쇄됩니다.

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n'
a b c  d e f    ¡ ¢ £ 

스크린샷에도 같은 내용이 있습니다.

xterm 및 gnome-terminal의 다른 출력을 보여주는 스크린샷

이는 더 명확한 경우에서 발생하는 것과 유사합니다.입력하다( \r)의 역할은 줄의 처음으로 다시 이동하는 것입니다. 이것이 바로 당신이 얻는 이유입니다:

$ printf '12345\r67890\n'
67890

터미널은 인쇄를 시작한 12345다음 \r로 덮어쓰여 줄의 시작 부분으로 다시 보냅니다. 12345따라서 67890표시되는 것은 이것이 전부 입니다 67890. 하지만 132345그것은 다른 프로그램으로 전송되지 않고 여전히 거기에 있으며 다른 문자들이 그것을 덮었기 때문에 단지 보이지 않을 뿐입니다:

$ printf '12345\r67890\n' | od -c
0000000   1   2   3   4   5  \r   6   7   8   9   0  \n
0000014

답변3

UTF8 문자 시퀀스를 출력하는 명령과 터미널 에뮬레이터 창(종종 "내 터미널 창"이라고 함)에 표시되는 디스플레이를 해석하고 있습니다.

그러면 설명하는 일련의 문자로 인해 터미널 에뮬레이터 창에 결과가 표시되지 않는 것 같습니다. "이 문자가 애플리케이션으로 전송되고 있습니까?"라고 묻습니다.

예, 터미널 에뮬레이터로 전달되어 수신된 문자 순서를 해석하고 창에 표시할 문자 모양을 결정합니다.

관련 정보