
Linux에서 cal을 실행하면 이번 달의 출력이 현재 날짜의 비디오 하이라이트를 반전시킵니다. 해당 출력을 hexdump -c로 보내면 몇 가지 흥미로운 결과를 얻습니다.
0000000 N o v e m b e r 2 0 1 6
0000010 \n S u M o T u
0000020 W e T h F r S a \n
0000030 1 2 _ \b _ \b 3
0000040 4 5 \n 6 7
0000050 8 9 1 0 1 1 1 2 \n
0000060 1 3 1 4 1 5 1 6 1 7 1
0000070 8 1 9 \n 2 0 2 1 2 2
0000080 2 3 2 4 2 5 2 6 \n 2 7
0000090 2 8 2 9 3 0
00000a0 \n
00000b0 \n
00000bc
보시다시피, 오늘 강조 표시된 '3' 앞에 _\b _\b라는 보이지 않는 시퀀스가 인쇄되고 있습니다. _ 밑줄(ASCII 16진수에서는 5F)이고 \b는 ASCII 16진수에서 Ctrl-H 또는 08입니다. 이게 뭔가요? 모호한 터미널 코드가 많이 있다는 것을 알고 있지만 \e[7m. 더 이상한 점은 다음 명령 중 하나와 같은 표준 printf 기능을 사용하여 동일한 문자를 인쇄해도 cal의 동일한 동작을 재현할 수 없다는 것입니다.
/usr/bin/printf "1 2 _\b _\b3 4 5\n"
/usr/bin/printf "1 2 _^H _^H3 4 5\n"
^H는 Ctrl-V Ctrl-H를 눌러 만들어집니다. 그러나 이들 중 어느 것도 cal과 동일한 역 비디오 출력을 생성하지 않습니다. 나는 심지어 그것을 하기 위해 작은 C 프로그램을 작성해 보았습니다. 나는 또한 echo -e를 사용해 보았습니다. 흥미로운 점은 터미널에서 비디오를 반전시키지는 않지만 less -R의 출력을 파이프하면 색상이 노란색으로 바뀌고 밑줄이 그어진다는 것입니다. 다른 터미널에서는 밑줄을 그어 보았습니다. 거의 오버스트라이크처럼 보이지만 _ 이외의 문자를 사용하면 작동하지 않아서 _\b가 단일 코드 시퀀스라고 생각하게 됩니다. 그러면 해당 캐릭터의 비디오는 어떻게 반전되나요?
이에 대한 통찰력이 있습니까?
매뉴얼 페이지에는 cal의 출력이 원래 Unix cal 명령에 대한 비트 호환 버전으로 가정되어 있다고 나와 있습니다. 그래서 나는 이것이 고대의 코드라고 추측할 뿐입니다.
답변1
거의 과한거 같긴한데
그것이 바로 그것이다. 에서 논의한 바와 같이80열 콘솔에 탭스톱이 11개 있는 이유는 무엇입니까?, Unix 터미널과 관련하여 기계식 타자기의 동작을 생각하는 것이 도움이 됩니다. 이 경우 문자 앞의 시퀀스 _
BS(백스페이스 문자)는 해당 문자의 밑줄을 표시하는 데 사용되는 규칙입니다. 일부 터미널에서는 텍스트에 밑줄을 긋는 방식이기 때문입니다. 대체 제어 순서는 _
문자 뒤의 BS입니다. 물론 원래 터미널에서는 무엇이 무엇을 압도하는지는 중요하지 않았습니다. 최신 비디오 단말기에서는 마지막 문자가 "승리"되어 이전 데이터가 삭제됩니다. 그러므로 _
학사 <문자>순서가 바람직합니다.
ncal
이 프로그램인 FreeBSD 에는 강조 표시와 관련하여 두 가지 작동 모드가 있습니다.
so
출력이 터미널인 경우 termcap 데이터베이스에서 현재 터미널 유형에 대한 및 시퀀스를 찾아se
강조 표시된 텍스트의 양쪽을 내보냅니다. (실제로 이 작업을 수행하는 코드에는 버그가 있습니다. 스택의 버퍼가 범위를 벗어나고 그 내용이 나중에 사용되는 것과 관련하여 아무도 발견하지 못한 것 같습니다.)- 출력이 터미널이 아닌 경우 강조 표시할 각 문자 앞에
_
BS 시퀀스가 오는 텍스트를 내보냅니다.
_
(물론) 귀하의 터미널이 밑줄을 긋는 터미널 중 하나가 아닌 한, BS 시퀀스를 터미널로 내보내는 방식으로 이를 복제할 수 없습니다 . 이는 터미널 에뮬레이터의 경우가 아니며 여기에서 사용하는 터미널이나 터미널 에뮬레이터의 경우도 거의 확실하지 않습니다.
그러나 다음을 수행할 수 있습니다.필터이 규칙을 사용하는 텍스트는 ul
프로그램을 통해 이 규칙과 다른 여러 타자기와 유사한 규칙을 인식하고 이를 터미널의 실제로 제어 시퀀스가 무엇이든 변환하여 termcap 데이터베이스에서 검색합니다. 를 printf
통해 명령 의 출력을 필터링할 수도 있습니다 ul
.
다른 터미널에서는 밑줄을 그어 보았습니다.
ncal
아이러니하게도 프로그램을 통해 비터미널 모드 출력을 필터링하는 것은 ul
실제로 ncal
터미널 제어 시퀀스 자체를 작성하는 것보다 약간 우수합니다. 반면ncal
터미널을 사용하는뛰어난방법,ul
터미널의 실제 사용을 시도합니다.밑줄BS 시퀀스를 변환할 때 모드(있는 경우) _
. termcap 매뉴얼에서 설명하는 것처럼 눈에 띄는 모드는 터미널에 적합한 것(굵은 글씨, 반전 비디오 또는 색상 포함)이 될 수 있으며 반드시 밑줄을 긋는 것은 아닙니다. 터미널 중 하나에서는 분명히 밑줄과 색상 변경이 조합되어 있습니다.
또한 ul
밑줄 시작/끝 시퀀스가 없지만 밑줄 마지막 문자 시퀀스가 있는 터미널에도 대처합니다. 아이러니하게도,ul
터미널이 다음과 같은 경우에는 대처할 것입니다.정말로_
각 문자 뒤에 BS를 붙여 밑줄을 긋는 반면 ncal
대처할 수는 없습니다.
물론 의 버퍼 처리 버그도 ul
없습니다 . ncal
☺
출력을 로 파이프하면
less -R
색상이 노란색으로 바뀌고 밑줄이 그어집니다.
당신이 발견한 바와 같이, 프로그램은 BS 시퀀스를 less
이해 하고 프로그램이 하는 것처럼 어느 정도 처리합니다. 완전히 동일하지는 않습니다. 여러 문자 및 BS 문자가 포함된 시퀀스를 처리할 수 있으며 굵은 글꼴에 대한 유사한 시퀀스도 처리할 수 있습니다. 할 수 없습니다. 다음 두 가지에서 보는 내용을 대조해 보세요._
ul
ul
_
less
/usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4.\b\b\b45 6\n" | 울
/usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4.\b\b\b45 6\n" | 더 적은
옛날 좋았던 시절로 돌아가
안타깝게도 지금은 여전히 "좋았던 시절"입니다. 사람들이 이것이 요즘 거의 사용되지 않는다고 믿도록 속이지 마십시오.
매뉴얼에는 없지만 소스 코드는 ul
"그것이 nroff
출력되는 것"이기 때문에 Teletype Model 37의 제어 시퀀스 처리를 구현하려고 시도하고 있음을 지적합니다. nroff
터미널이 색상, 볼드체, 이탤릭체와 같은 멋진 기능을 얻은 지 오랜 후에 작성된 원래 Unix 프로그램에 대한 GNU 대체품은 다음 을 생성할 수 있습니다.ECMA-48색상, 볼드체, 이탤릭체에 대한 제어 순서입니다. 실제로도 그렇죠일반적인 경우.
nroff
, 및 GNU 대체품은 터미널에 표시할 매뉴얼 페이지의 형식을 지정하는 데 사용됩니다. 슬프고 아이러니하게도 GNU 도구가 작성된 지 약 10년이 지나면서 사람들은 GNU 도구를 사용하여 1976년의 "새로운" ECMA-48 제어 시퀀스 대신 1968년의 오래된 Teletype Model 37 시퀀스를 생성했습니다(sic!). 그들은 기본 동작을 수정하는 옵션으로 man
호출을 만들고 추가 ditroff 출력을 강제하는 문서화되지 않은 파일을 추가했습니다.groff
터미널에서 매뉴얼 페이지를 읽을 때마다 수동 소스 텍스트를 이전 Teletype Model 37 제어 시퀀스를 사용하여 터미널의 제어 시퀀스로 변환하는 출력 문자 스트림으로 충실하게 변환하는 수동 시스템이 실행 groff
됩니다 .less
more
추가 읽기
답변2
Ctrl-H
백스페이스는 커서를 한 단계 왼쪽으로 이동합니다. 밑줄, 백스페이스 및 기타 문자를 보내는 것은 옛날에는 하드 카피("종이") 터미널에서 무언가에 밑줄을 긋는 방법이었습니다. 이는 의 출력에서 현재 날짜를 강조하는 데 사용되었습니다 cal
.
내 cal
프로그램이 실행될 때 konsole
이 시퀀스를 출력하지 않습니다. script -c cal
결과 파일을 실행하고 검사하면 cal 프로그램이 이스케이프 시퀀스를 사용하여 역 모드 비디오로 전환하는 것을 typescript
볼 수 있습니다 .<esc>[7m