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는 Ctrl-H 또는 ASCII 16진수에서 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입니다. 물론 초기 터미널에서는 무엇보다 무엇이 중요한지는 중요하지 않습니다. 최신 비디오 단말기에서는 마지막 문자가 "승리"로 기록되어 이전 데이터가 삭제됩니다. 따라서 _
B.S. <문자>순서가 우선합니다.
FreeBSD ncal
, 즉 프로그램에는 강조 표시와 관련하여 두 가지 작동 모드가 있습니다.
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" |ur
/usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4.\b\b\b45 6\n" |
좋았던 옛날로 돌아가
안타깝게도 지금은 여전히 "좋았던 시절"입니다. 요즘에는 이 기능이 거의 사용되지 않는다고 사람들이 속이는 일이 없도록 하십시오.
매뉴얼에는 없지만 소스 코드에는 ul
"그게 출력이기 때문에" Teletype Model 37에 대한 제어 시퀀스 처리를 구현하려고 한다고 명시되어 있습니다 nroff
. nroff
터미널이 색상, 볼드체, 이탤릭체와 같은 고급 기능을 획득한 지 오랜 후에 작성된 원본 Unix 프로그램에 대한 GNU 대체품이 생성될 수 있었습니다.ECMA-48색상, 볼드체 및 이탤릭체에 대한 제어 순서입니다. 사실 그렇죠정상적인 상황에서.
nroff
터미널에 표시하기 위한 매뉴얼 페이지 형식 지정을 위한 GNU 대체품입니다. 슬프고도 아이러니하게도 GNU 도구가 작성된 지 약 10년이 지나면서 사람들은 1976년의 "새로운" ECMA-48 제어 시퀀스 대신 1968년의 오래된 Teletype Model 37 시퀀스를 생성하도록 GNU 도구를 차단하기 시작했습니다. 이 방법!). 기본 동작을 수정 하고 추가 ditroff 출력을 강제하는 문서화되지 않은 파일을 추가하는 옵션과 함께 man
호출 됩니다.groff
터미널에서 매뉴얼 페이지를 읽을 때마다 수동 시스템이 실행되어 터미널 제어 시퀀스로 변환 중이 거나 변환 중인 groff
이전 Teletype Model 37 제어 시퀀스를 사용하여 수동 소스 텍스트를 출력 문자 스트림으로 충실하게 변환합니다 .less
more
추가 읽기
답변2
Ctrl-H
백스페이스 키는 커서를 왼쪽으로 한 단계 이동하는 키입니다. 예전에는 밑줄, 백스페이스 및 기타 몇 가지 문자를 보내는 것이 하드 카피("종이") 터미널에서 무언가에 밑줄을 긋는 방법이었습니다. 이는 출력에서 현재 날짜를 강조 표시하는 데 사용됩니다 cal
.
내 프로그램은 cal
실행 시 konsole
이 시퀀스를 출력하지 않습니다 . 생성된 파일을 실행 script -c cal
하고 검사 하면 cal 프로그램이 이스케이프 시퀀스를 사용하여 역방향 비디오 모드로 전환하는 typescript
것을 볼 수 있습니다 .<esc>[7m