
가끔 컬이나 로컬 파일 시스템에서 바이너리를 가져옵니다. 대부분의 경우 손상된 터미널은 다음을 사용하여 수리할 수 있습니다.초기화. 다른 경우, 특히 바이너리가 큰 경우 터미널은 다음과 같은 출력을 인쇄하면서 몇 분 동안 멈춥니다.
또한 ~으로 알려진
c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
이 장면에 대해 세 가지 질문이 있습니다.
- 2c1은 무슨 뜻인가요? 터미널이 이것을 인쇄하는 이유는 무엇입니까?
cat
대화형 세션에서 이러한 나쁜 동작이 실제로 방지된 상황을 본 적이 있습니까 ?- 그러한 고양이(cee 또는 golang)를 프로그래밍하는 방법에 대한 제안 사항이 있습니까?
나의 초기 본능은 이것을 감지하기 위해 cat을 함수로 감싸는 것이었지만 이것이 꽤 어렵고 극단적인 경우가 많다는 것을 빨리 깨달았습니다.
function cat() {
# warn user if
# - argument 1 is a large executable
# - argument 1 to the previous command in the a pipe-chain looks like a large binary
# abort if
# - session is interactive and we are able to detect 2c1 garbage
}
실용적인 해결책은 "안전하지 않은" 입력을 볼 때 항상 less(LESSPIPE 사용)를 사용하는 것일 수 있지만 이 질문은 호출기와는 아무 관련이 없습니다. 튜브 수가 점점 줄어들고 있다는 것을 알고 있습니다. 나는 매일 적극적으로 사용합니다. 어쩌면 덜 + 덜 통제할 수도 있습니다이 문제에 대한 해결책은 Less의 저자가 약 20~30년 전에 동일한 문제를 구현한 것입니다..
그러나 cat은 여러 면에서 "호출기"와 다릅니다. 가장 중요한 점은 cat이 대화형이 아니라는 것입니다. 이것은 나에게 많은 의미가 있습니다.
less+lesspipe에 대한 제안은 실제로 매우 훌륭합니다(IMHO). 하지만 저는 제어 문자의 특성, 특수 이스케이프 시퀀스 및 다양한 터미널이 이러한 입력을 처리하는 방식에 더 관심이 있습니다.
나는 제어 문자의 기술적 세부 사항과 터미널이나 셸이 "쓰레기"와 제어 문자를 해석하는 방법에 더 관심이 있습니다. 나는 "이 문제를 어떻게 해결하시겠습니까?"라고 묻는 것이 아닙니다. 나는 "왜 터미널이 바이너리 파일을 이런 식으로 처리하는가"라고 물었습니다.
답변1
나는 이것을 바이너리에 대해 경고하는 데 사용 less
하고 일부 시스템에서는 다양한 유형을 처리합니다(예를 들어CentOS 7에서는 less file.rpm
RPM으로 파일을 볼 수 있습니다. 나는 이것이 "레스파이프(lesspipe)"라고 불린다고 믿는다.
또한 다음에 이런 일이 발생하면 정상으로 reset
돌아갈 수 있습니다 tput reset
. 그들은 터미널에 이스케이프 시퀀스를 보내 기본 일반 상태로 재설정하도록 지시하고 stty sane
tty 장치 파일의 설정을 일반 기본값으로 변경하는 것과 동일한 작업을 수행합니다(바이너리 덤프가 이러한 설정에 영향을 주어서는 안 됨). reset
또한 tty 장치 파일의 터미널 또는 터미널 에뮬레이터 창 크기 개념(보고된 대로 tty size
)을 수정하고 이에 대한 터미널 쿼리를 지원합니다.
답변2
아무도 "문자열"을 언급하지 않았습니다. string은 cat과 정확히 동일하지는 않지만 인접한 텍스트 데이터의 텍스트 문자열만 인쇄하므로 터미널에서 보는 것이 더 안전합니다. 일반적으로 binutils 패키지와 함께 제공됩니다. 이것은 인쇄된 데이터에서 바이너리 출력을 얻지 못하도록 신속하게 확인하는 편리한 프로그램이며, 연속된 비바이너리 데이터를 보려는 경우에도 유용합니다. 기본적으로 4개 이상의 ASCII 문자를 포함하는 텍스트의 연속 부분만 인쇄합니다. 이는 -n 옵션을 사용하여 조정할 수 있습니다.
답변3
직렬 회선이나 pseudo-tty 장치(직렬 회선을 에뮬레이트하는)를 통해 터미널 또는 터미널 에뮬레이터와 상호 작용할 수 있습니다.
커널에는 일종의 적응 계층으로 중간에 위치하여 몇 가지 변환을 수행하는 소프트웨어 모듈이 있지만(나중에 간략하게 설명) 일반적으로 다음을 수행합니다.
- 이 직렬 회선을 통해 바이트 스트림을 터미널로 보냅니다. 터미널은 이를 화면에 렌더링할 문자 또는 동작을 변경하기 위한 특수 지침으로 해석합니다.
- 그 대가로 터미널은 사용자가 입력한 내용이나 수신한 일부 제어 쿼리에 대한 응답으로 컴퓨터에 알리기 위해 직렬 회선의 다른 회선을 통해 컴퓨터에 바이트 스트림을 보냅니다.
예를 들어, 터미널은 ISO8859-1(latin1 터미널이라고도 함)로 구성될 수 있습니다. 즉, 0x53 0x74 0xe9 0x70 0x68 0x61 0x6e 0x65를 수신하면 터미널이 S
화면의 현재 커서 위치에 있는 것으로 해석됩니다. 대신 사용자가 입력하면 터미널은 0x53바이트를 보냅니다.t
é
p
h
a
n
e
S
0~0x1f 범위의 바이트 값은 다음과 같이 해석됩니다.제어수치. 즉, 글리프로 표현되지 않고 오히려 특별한 의미를 갖는다.
예를 들어:
- 0x7(BEL) 오디오 또는 시각적 경고 생성
- 0x8(BS) 커서가 왼쪽으로 이동합니다.
- 0xa(LF) 커서가 아래로 이동합니다.
- 0xd(CR)는 커서를 화면의 첫 번째 열로 이동합니다.
- 0x9(TAB) 커서를 다음 탭으로 이동
이 범위에는 32개의 제어 문자만 있으며 대부분의 터미널에는 이를 제어할 수 있는 더 많은 기능이나 방법이 있습니다. 따라서 이 외에도 다음보다 더 많은 것을 보낼 수 있습니다.하나터미널을 제어하는 바이트입니다. 대부분의 터미널과 시퀀스의 경우 첫 번째 바이트는 0x1b(ESC)이고 그 뒤에는 하나 이상의 바이트가 옵니다.
예를 들어 위에 표시된 것처럼 커서를 왼쪽이나 아래로 이동하는 제어 문자는 있지만 오른쪽이나 위로 이동하는 제어 문자는 없습니다(원래 텔레타이프 기계에서는 오른쪽이 "스페이스"로 이루어지지만 CRT에서는 터미널에서는 커서 아래에 있는 내용이 지워지고 텔레타이프를 사용하면 용지 걸림이 발생할 수 있으므로 이러한 터미널에는 이스케이프 시퀀스가 도입되어야 합니다. 대부분의 터미널에서는 0x1b 0x5b 0x43 및 0x1b 0x5b 0x41입니다. (덧붙여 말하면, 이는 눌렀을 때 많은 터미널 Right과 그러한 키가 있는 터미널 에서 전송되는 바이트 시퀀스이기도 합니다 Up.)
이제 터미널에서 지원되는 이스케이프 시퀀스는 다음과 같습니다.
- 텍스트나 배경색, 기타 그래픽 렌더링 속성 변경
- 문자 세트를 변경합니다. 예를 들어 latin1에는 그리스어 문자가 없으며 터미널(유니코드 이전부터 현재까지)은 다른 언어의 알파벳 또는 블록 다이어그램 문자를 표시하기 위해 다른 문자 세트로 전환하는 것을 지원합니다.
- 탭 정지 위치 설정
- 커서 위치, 색상, 창 제목, 크기 등의 정보를 터미널에서 쿼리할 수 있습니다.
- 입력이 처리되는 방식에 영향을 줄 수 있습니다. 예를 들어, 일부 터미널은 Shift+ 를 누를 때 A0x41(ASCII ) 문자를 전송하지 않고
A
해당 수정자(shift, alt, ctrl... .) 및 키에 대한 일련의 바이트를 전송 하는 모드 입력을 지원합니다. 코드 정보가 인코딩됩니다. - 일부 X11 터미널 에뮬레이터는 이스케이프 시퀀스를 인식하여 글꼴, 창 크기를 변경하고 JPEG 이미지를 표시하고 화면 내용을 프린터로 보낼 수 있습니다.
텍스트 파일에는 일반적으로 그래픽 문자를 나타내는 바이트(또는 UTF-8 또는 기타 멀티바이트 문자 집합의 경우 바이트 시퀀스)만 있습니다. 오직제어텍스트 파일에서 찾을 수 있는 문자는 NL(0xa, 일명 LF) 및 TAB(0x9)입니다.
이렇게 하면 cat file.txt
단순히 cat
내용을 읽고 file.txt
표준 출력에 씁니다. stdout이 직렬 또는 의사 tty 장치 파일(예:)이고 /dev/ttyS0
터미널 /dev/pts/0
라인 규칙이 여기에 푸시되는 경우 마치 터미널 에뮬레이터의 대화형 쉘에서 명령을 실행하는 것처럼 라인 규칙은 이러한 NL을 CR로 변환합니다. +NL(NLNL은 CRNLNL로 번역될 수 있음), 터미널은 CRNL을 수신한 후 커서를 처음으로 이동한 다음 아래로 이동합니다.
따라서 파일의 텍스트가 터미널의 문자 집합으로 인코딩되면 파일 내용의 텍스트가 터미널 화면에 표시됩니다.
이제 실행 파일 또는 기타 임의 바이너리의 바이트는 문자를 나타내기 위한 것이 아니며 0에서 31 범위의 값을 포함하여 모든 값을 가질 수 있으므로 터미널로 전송되면 터미널은 지시하는 대로 수행합니다. 이를 제어 문자로 수행하고 해석하면 위에 나열된 작업 이상을 수행하고 완전히 사용할 수 없게 될 수 있습니다.
이를 방지하려면 먼저 이러한 파일을 터미널에 보내지 마십시오. 이는 말이 되지 않거나 파일이 텍스트 파일(또는 의도된 파일)일 가능성이 있는지 알 수 없는 경우입니다. 사용자가 그대로 볼 수 있음) 터미널에 대한 이스케이프 시퀀스 포함고의로터미널에서 해석되는지 여부에 관계없이 제어 문자(최소한 TAB 및 NL을 제외한 모든 문자)를 제거하거나 이를 시각적으로 그래픽으로 표현하는 도구를 사용할 수 있습니다.
이것이 바로 많은 구현 지원 -v
및 옵션의 기능입니다. 여기서 NL 및 TAB를 제외한 모든 문자는 비ASCII 문자의 일반적인 시각적 표현인 바이트 0~31 및 0x7f, 바이트 0x80~0x9f 및 0xff, 바이트 0xa0~0xfe의 일부 표현으로 변환됩니다. 그리고 TAB(으로 변경됨)에서만 작동합니다.-t
cat
-v
^X
M-^X
M-X
-t
^I
또는 기본적으로 이 작업을 수행 하는 less
또는 같은 호출기를 사용할 수 있으며 (적어도 / raw 옵션을 사용하지 않는 한 ) ASCII가 아닌 문자를 변환하지 않는다는 점에서 조금 더 똑똑합니다. 해당 로케일의 그래픽 표현 색상 지정 또는 강조 표시 모드를 사용하여 어떤 바이트가 변환되었는지 더 명확하게 표시합니다.vim
view
-r
-R
또는 hexdump -C
.xxd
l
which 명령이 보다 명시적인 방식으로 유사한 작업을 수행 하고 표준(반대)인 경우 도 참조하세요.sed
cat -vte
cat -vte
sed -n l < a-file
답변4
- 응, 젊은 견습생.
$ cargo search bat
bat = "0.23.0" # A cat(1) clone with wings.
- 그런데 선생님, 물건이 뭐예요?
$ cargo --help |any install rust
Rust's package manager
--list List installed commands
--explain <CODE> Run `rustc --explain CODE`
install Install a Rust binary. Default location is $HOME/.cargo/bin
uninstall Uninstall a Rust binary
$ cargo install bat
(...)
주인:바이너리 파일을 사용하려고 하면 bat
이런 일이 발생합니다 .
$ bat `which bat`
[bat warning]: Binary content from file '/home/jaroslav/.cargo/bin/bat'
will not be printed to the terminal (but will be present if the output
of 'bat' is piped). You can use 'bat -A' to show the binary file contents.
- 도제:스승님, 타격에 불이익이 있나요?
- 주인:예, 대용량 파일을 처리할 때 속도가 느려질 수 있지만 이는 부분적으로 구조화된 구문을 강조하기 때문입니다. --style=plain --color=never와 같이 비활성화할 수 있습니다.
- 도제:그럼 스승님, cat이 터미널에 출력하는 이상한 문자는 어떻습니까?
- 주인:이는 터미널이 ANSI 이스케이프 코드(내부 터미널 명령)처럼 보이는 모든 것을 기꺼이 받아들이고 해석하고 명령이 말하는 대로 수행하려고 시도하기 때문에 발생합니다(해당 명령이 구현된 경우). 간단한 소개를 보려면 다음을 확인하세요.Ansi 색상 이스케이프 시퀀스 목록
이 동작을 재현하는 방법은 다음과 같습니다.
$ echo -ne "\u1B\u5B\u63" | xxd
00000000: 1b5b 63 .[c
$ echo -ne "\u1B\u5B\u63"
^[[?1;2c
$ 1;2c