셸에서 제어 문자(^C, ^D, ^[,...)를 다양한 방식으로 표시하는 방법

셸에서 제어 문자(^C, ^D, ^[,...)를 다양한 방식으로 표시하는 방법

셸에 제어 문자를 입력하면 "캐럿"이라는 문자를 사용하여 표시됩니다. 예를 들어 이스케이프 ^[문자는 캐럿으로 작성됩니다.

나는 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으로 변환됩니다 . 처럼 백스페이스로 삭제했기 때문에 앱에는 들어가지 않았습니다.^XB

\r(일명 )은 에코의 경우 ( ), 애플리케이션의 경우 ( ) ^M로 번역됩니다 .\r\n^M^J\n^J

그렇다면 이 사람들을 위한 우리의 선택은 무엇입니까?무음애플리케이션:

  • 장애를 입히다 echo( stty -echo). 이는 아무것도 에코하지 않음으로써 제어 문자가 에코되는 방식을 효과적으로 변경합니다. 실제 해결책은 아닙니다.
  • 장애가 있는 echoctl. 이는 제어 문자( ^H, ^M... 및 행 편집기에서 사용되는 기타 모든 문자 제외)가 반향되는 방식을 변경합니다 . 그때 그들은에코있는 그대로. 즉, 예를 들어 ESC 문자는 \e( ^[/ 0x1b) 바이트(터미널에서 이스케이프 시퀀스의 시작으로 인식함)로 전송되고, (BEL, 터미널에서 경고음이 울리게 함) ^G을 전송하면 ... \a옵션.
  • 굵은 선 편집기( stty -icanon)를 비활성화합니다. 원래 응용 프로그램의 유용성이 크게 줄어들기 때문에 이는 실제로 옵션이 아닙니다.
  • 커널 코드를 편집하여 tty 라인 규칙의 동작을 변경하여 다음과 같이 하십시오.에코\e[7m^X\e[m단순히 전송하는 대신 문자 전송을 제어합니다 ^X( \e[7m역방향 비디오는 일반적으로 대부분의 터미널에서 여기에서 활성화됩니다).

한 가지 옵션은 어리석은 응용 프로그램에 멋진 줄 편집기를 추가하는 이와 같은 래퍼를 사용하는 것입니다 rlwrap. 이는 더러운 해킹입니다. 이 래퍼는 실제로 read()터미널 장치의 간단한 s를 readline 줄 편집기에 대한 호출로 대체하려고 시도합니다(tty 줄 규칙의 모드를 변경함).

한 단계 더 나아가 다음과 같은 솔루션을 시도해 볼 수도 있습니다.이것GNU 화면의 기능을 사용하여 터미널의 모든 입력을 하이재킹하여 zsh의 라인 편집기를 통과합니다( ^X역방향 비디오에서 s가 강조 표시됨).:exec

이제 자체 라인 편집기를 구현하는 응용 프로그램의 경우 방법을 결정하는 것은 응용 프로그램에 달려 있습니다.에코이미 마쳤어. bash사용자 정의 제어 문자 반향 방법을 지원하지 않는 함수를 구현하려면 readline을 사용하십시오.

에 대해서는 zsh다음을 참조하세요.

info --index-search='highlighting, special characters' zsh

zsh인쇄할 수 없는 문자는 기본적으로 강조 표시됩니다. 다음과 같이 강조 표시를 사용자 정의할 수 있습니다.

zle_highlight=(special:fg=white,bg=red)

해당 특수 문자의 경우 빨간색 배경에 흰색 텍스트가 강조 표시됩니다.

그러나 이러한 문자의 텍스트 표현은 사용자 정의할 수 없습니다.

^XUTF-8 로케일에서 0x18은 , \u378, \U7fffffff(할당되지 않은 두 개의 유니코드 코드 포인트)로 <0378>, <7FFFFFFF>, \u200b(인쇄할 수 없는 유니코드 문자) 로 렌더링됩니다 <200B>.

\x80iso8859-1 로케일에서는 ...etc로 렌더링됩니다 ^�.

답변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"이 아닌 모든 종료 상태 코드가 표시됩니다.

관련 정보