%EB%A5%BC%20%EB%8B%A4%EB%A5%B4%EA%B2%8C%20%ED%91%9C%EC%8B%9C%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
쉘에 제어 문자를 입력하면 "캐럿 표기법"을 사용하여 표시됩니다. 예를 들어 이스케이프는 ^[
캐럿 표기법 으로 작성됩니다 .
나는 bash 쉘을 멋지게 보이도록 사용자 정의하는 것을 좋아합니다. 예를 들어 나는 나의 색을 바꾸었 PS1
습니다 PS2
. 이제 제어 캐릭터가 일반 캐릭터와 더욱 구별되도록 독특한 모양을 갖게 되기를 원합니다.
$ # Here I type CTRL-C to abort the command.
$ blahblah^C
^^ I want these two characters to be displayed differently
쉘 강조 제어 문자를 다르게 만드는 방법이 있습니까?
굵은 글꼴로 표시하거나 일반 텍스트와 다른 색상으로 표시되도록 할 수 있습니까?
나는 사용하고있다세게 때리다bash
여기에는 쉘이 있지만 다양한 쉘에 적용되는 솔루션이 있을 수 있으므로 질문에 태그를 지정하지 않았습니다 .
메모제어 문자 강조가 어느 수준에서 발생하는지 알 수 없습니다. 나는 처음에 그것이 껍질 자체에 있다고 생각했습니다. 이제 그런 말을 들었습니다.판독선제어 문자가 다음과 같은 셸에 있는 방식을 제어합니다.세게 때리다. 이제 질문에 태그가 지정되었으며 readline
여전히 답변을 찾고 있습니다.
답변1
를 누르면 Ctrl+X터미널 에뮬레이터가 의사 터미널 쌍의 마스터 측에 바이트 0x18을 씁니다.
다음에 무슨 일이 일어날지는 tty 라인 규칙(마스터 측(에뮬레이터의 제어 하에 있음)과 슬레이브 측(터미널에서 실행 중인 애플리케이션이 상호 작용함) 사이에 있는 커널의 소프트웨어 모듈)이 어떻게 구성되는지에 따라 달라집니다.
이를 구성하는 명령tty 라인 규율명령 입니다 stty
.
그런 멍청한 애플리케이션을 실행하면 cat
표준 입력이 터미널인지 아닌지를 인식하지 못하고 상관하지도 않습니다. 터미널은 기본값입니다.표준적인tty 라인 규율이 조잡한 코드를 구현하는 모드라인 편집기.
그보다 더 많은 것이 필요한 일부 대화형 애플리케이션라인 편집기일반적으로 시작할 때 해당 설정을 변경하고 떠날 때 복원합니다. 현대 껍질,그들의 프롬프트에그러한 응용 프로그램의 예입니다. 그들은 자신만의 고급 라인 편집기를 구현합니다.
일반적으로 명령줄을 입력하는 동안 쉘은 tty 라인 규칙을 해당 모드로 설정하고 Enter를 눌러 현재 명령을 실행하면 쉘은 일반 tty 모드를 복원합니다(프롬프트를 실행하기 전에 적용되었던 대로).
명령 을 실행하면 stty -a
현재 사용 중인 설정이 표시됩니다.멍청한 애플리케이션. icanon
및 설정 echo
이 echoctl
활성화되는 것을 볼 수 있습니다 .
이것이 의미하는 바는 다음과 같습니다.
icanon
: 원유 라인 편집기가 활성화되었습니다.echo
: 사용자가 입력하는 문자(터미널 에뮬레이터가 마스터 측에 쓰는 문자)는반향되었다뒤로(터미널 에뮬레이터에서 읽을 수 있음)echoctl
: 대신에반향되었다Asis, 제어 문자는 다음과 같습니다반향되었다처럼^X
.
을 입력한다고 가정해 보겠습니다 A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return.
터미널 에뮬레이터는 다음을 전송합니다: AB\bC\x18\b\r
. 라인 규율은에코back: AB\b \bC^X\b \b\b \b\r\n
, 슬레이브 측( /dev/pts/x
)에서 입력을 읽는 애플리케이션은 을 읽습니다 AC\n
.
응용 프로그램이 보는 모든 것은 이며 AC\n
, 누를 때만 표시되므로 거기 Enter에 대한 출력을 제어할 수 없습니다 ^X
.
당신은 그것을 알아 차릴 것입니다에코, 첫 번째 ^H
( ^?
일부 터미널의 경우 erase
설정 참조) 결과가 \b \b
터미널로 다시 전송되었습니다. 이는 커서를 뒤로 이동하고, 공백으로 덮어쓰고, 커서를 다시 뒤로 이동하는 순서이며, 두 번째는 해당 두 문자 를 지우는 ^H
결과를 가져왔습니다 .\b \b\b \b
^
X
(0x18) 자체 가 출력 으로 ^X
변환되고 있었습니다 . 처럼 백스페이스로 삭제했기 때문에 애플리케이션에 반영되지 않았습니다.^
X
B
\r
(일명 )은 에코의 경우 ( )로, 애플리케이션의 경우 ( ) ^M
로 변환되었습니다 .\r\n
^M^J
\n
^J
그렇다면 이에 대한 우리의 선택은 무엇입니까?멍청한신청:
- 장애를 입히다
echo
(stty -echo
). 이는 아무것도 에코하지 않음으로써 제어 문자가 에코되는 방식을 효과적으로 변경합니다. 실제로 해결책은 아닙니다. - 장애를 입히다
echoctl
. 이는 제어 문자(^H
,^M
... 및 줄 편집기에서 사용되는 다른 모든 문자 제외)가 반향되는 방식을 변경합니다 . 그들은 그때반향되었다있는 그대로. 예를 들어, ESC 문자는\e
(^[
/0x1b
) 바이트(터미널에서 이스케이프 시퀀스의 시작으로 인식됨)로 전송되고,^G
사용자는\a
(BEL, 터미널 경고음을 울림)... 옵션이 아닙니다. . - 원유 라인 편집기를 비활성화합니다(
stty -icanon
). 원유 애플리케이션의 유용성이 훨씬 떨어지기 때문에 실제로는 옵션이 아닙니다. - 커널 코드를 편집하여 tty 라인 규칙의 동작을 변경하여에코
\e[7m^X\e[m
대신에 제어 문자가 전송됩니다^X
(여기서는\e[7m
일반적으로 대부분의 터미널에서 역방향 비디오를 활성화합니다).
옵션은 rlwrap
멍청한 애플리케이션에 멋진 라인 편집기를 추가하는 더러운 해킹과 같은 래퍼를 사용하는 것입니다. 실제로 해당 래퍼는 read()
터미널 장치의 간단한 s를 readline 라인 편집기에 대한 호출로 대체하려고 시도합니다(tty 라인 규칙의 모드를 변경함).
더 나아가 다음과 같은 솔루션을 시도해 볼 수도 있습니다.이 하나^X
이는 터미널의 모든 입력을 가로채서 GNU 화면 기능에 의존하는 zsh의 라인 편집기(역상 비디오에서 s를 강조 표시함)를 통과합니다 :exec
.
이제 자체 라인 편집기를 구현하는 응용 프로그램의 경우, 방법을 결정하는 것은 응용 프로그램의 몫입니다.에코수행. bash
제어 문자가 에코되는 방식을 사용자 정의하는 기능을 지원하지 않는 경우 readline을 사용합니다.
에 대해서는 zsh
다음을 참조하세요.
info --index-search='highlighting, special characters' zsh
zsh
기본적으로 인쇄할 수 없는 문자를 강조 표시합니다. 예를 들어 다음을 사용하여 강조 표시를 사용자 정의할 수 있습니다.
zle_highlight=(special:fg=white,bg=red)
해당 특수 문자를 빨간색 바탕에 흰색으로 강조 표시합니다.
하지만 해당 문자의 텍스트 표현은 사용자 정의할 수 없습니다.
^X
UTF-8 로케일에서 0x18은 , \u378
, \U7fffffff
(할당되지 않은 두 개의 유니코드 코드 포인트)로 <0378>
, <7FFFFFFF>
, \u200b
(실제로 인쇄할 수 없는 유니코드 문자) 로 렌더링됩니다 <200B>
.
\x80
^�
iso8859-1 로케일에서는 ... 등 으로 렌더링됩니다 .
답변2
나는 일반적으로 .bashrc 파일에 다음 코드를 가지고 있습니다.
function get_exit_status()
{
local code=$?
if [ $code -ne 0 ]
then
printf $'\001\033[31m\002'"($code)"$'\001\033[0m\002'" "
fi
}
그런 다음 PS1에서 이 함수를 호출합니다.
PS1='\u@\h \w $(get_exit_status)'
따라서 ^C를 누르면 프롬프트에 표시됩니다.
I@mycomputer ~ ^C
I@mycomputer ~ (130)
"0"이 아닌 모든 종료 상태 코드가 표시됩니다.