![인쇄되지 않는 이스케이프 시퀀스: 언제?](https://linux55.com/image/56559/%EC%9D%B8%EC%87%84%EB%90%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EC%9D%B4%EC%8A%A4%EC%BC%80%EC%9D%B4%ED%94%84%20%EC%8B%9C%ED%80%80%EC%8A%A4%3A%20%EC%96%B8%EC%A0%9C%3F.png)
나는 최근에 터미널에서 색상을 많이 다루었기 때문에 이스케이프 시퀀스를 사용했습니다. 나는 Bash 맨페이지의 관련 섹션과 웹에서 많은 유용한 페이지를 읽었습니다.
예를 들어 멋지고 다채로운 Bash 프롬프트 등 내가 원하는 대부분을 얻었습니다. 즉, "비인쇄 이스케이프 시퀀스" 문자를 사용해야 하는 경우(또는 사용해야 하는 경우)에 대해 여전히 약간 혼란스럽습니다. 그것들은 \[
과 입니다 \]
.
만약 내가아니요프롬프트를 정의할 때 PS1에서 이를 사용하면 프롬프트가 올바르게 표시되지 않습니다. 사용하면 모든 것이 괜찮습니다. 좋아요
그러나 PS1 외부에서는 동일하게 작동하지 않는 것 같습니다. 예를 들어 스크립트를 더 읽기 쉽게 만들기 위해 $RGB_PURPLE
간단한 함수를 통해 설정되는 변수를 정의했습니다 c8_rgb()
. 최종 결과는 변수 \[\e[01;38;05;129m\]
에 굵은 보라색 전경색을 켜는 값이 포함된다는 것입니다.
PS1에서 이 변수를 사용하면 예상한 대로 작동합니다. 통과하거나 printf
사용 하면 echo -e
"반"이 작동합니다. 이 명령 printf "${RGB_PURPLE}TEST${COLOR_CLR}\n"
( COLOR_CLR
텍스트 속성을 재설정하는 이스케이프 시퀀스는 어디에 있습니까?)은 다음과 같이 표시됩니다. \[\]TEST\[\]
여기서 첫 번째 \[
와 마지막을 제외한 모든 항목은 \]
보라색으로 표시됩니다.
왜 차이가 있나요? 이러한 괄호가 인쇄되어 있지만 터미널에서 처리되지 않는 이유는 무엇입니까? 다른 방법으로 인쇄할 때와 마찬가지로 프롬프트의 일부로 인쇄할 때에도 동일하게 처리되었으면 좋았을 것입니다. 나는 이 변화를 이해하지 못한다.
경험적으로 보면 이러한 역할은~ 해야 하다프롬프트 정의에 사용되는 반면해서는 안 된다거의 모든 다른 상황에서 사용할 수 있습니다. 이로 인해 c8_rgb()
이스케이프 시퀀스 생성 및 출력을 처리하기 위해 위에서 언급한 것과 같은 범용 함수를 사용하기가 어렵습니다. 함수는 해당 결과가 프롬프트 구성에 있는지 아니면 다른 곳에 있는지 알 수 있는 방법이 없기 때문입니다.
한 가지 더 빠른 관련 질문: 이스케이프 시퀀스 출력 측면에서 본질적으로 동일합니까 echo -e
? printf
나는 보통 printf를 사용하는데, 다른 것보다 더 선호할 이유가 있나요?
이 명백한 뉘앙스를 설명할 수 있는 사람이 있나요? 터미널에서 이스케이프 시퀀스(보통 색상만 해당)를 사용할 때 알아야 할 다른 이상한 사항이 있습니까? 감사해요!
답변1
$PS1에서 인쇄되지 않는 문자를 사용할 때 "인쇄되지 않는 이스케이프 시퀀스"가 필요합니다. 명령줄을 편집할 때 화면을 올바르게 업데이트하려면 bash가 커서의 위치를 알아야 하기 때문입니다. Bash는 $PS1 프롬프트의 문자 수(커서가 있는 열 번호)를 계산하여 이를 수행합니다.
하지만 인쇄되지 않는 시퀀스를 $PS1에 넣으면 카운트가 잘못되고, 명령줄을 편집하면 줄이 엉망이 될 수 있습니다. 따라서 포함된 바이트를 계산하지 않아야 함을 나타내기 위해 \[
및 플래그가 도입되었습니다 .\]
답변2
나는 다음을 사용하여 충분한 해결책을 찾았습니다.8진수전체 이스케이프 시퀀스이며 구분 기호의 readline 형식을 사용합니다. PS1, echo -e 및 printf는 모두 정확히 동일한 문자열을 사용하여 이러한 방식으로 올바른 작업을 수행합니다. 저는 이것을 OSX의 Bash 4와 Linux의 Bash 3에서 테스트했습니다.
여기 답변에서 \001 및 \002에 대한 아이디어를 얻었습니다.https://superuser.com/questions/301353/escape-non-printing-characters-in-a-function-for-a-bash-prompt?rq=1
예:
$ TextGreen='\001\033[0;32m\002'
$ TextReset='\001\033[0m\002'
$ SomeString="${TextGreen}prompt_stuph${TextReset} \$ "
$ #
$ # now all of the following work as expected
$ #
$ PS1="$SomeString"
$ printf "$SomeString"
$ echo -e "$SomeString"
답변3
마찬가지로 ␛[01;38;05;129m
첫 번째 문자 ␛
는 터미널 이스케이프 시퀀스인 ASCII 이스케이프 문자(U+0027)입니다. 이는 터미널에 색상 129로 굵고 깜박이는 텍스트를 표시하기 시작하도록 지시합니다. 이스케이프 문자(inside , in , in 및 in ) \e
에 대한 bash 구문입니다 .$'…'
PS1
echo -e
printf
\[
터미널 이스케이프 시퀀스가 아니며 \]
bash 프롬프트 이스케이프 시퀀스입니다. 터미널로 전송되지 않고 bash에 의해 해석됩니다. 그들의 목적은 그 사이에 있는 문자가 인쇄되지 않는 문자임을 bash에게 알려주는 것입니다. 따라서 프롬프트의 너비는 실제로 안에 없는 문자의 수입니다 \[…\]
. Bash는 줄 편집기에서 커서 위치를 계산하기 위해 프롬프트의 너비를 알아야 합니다.
\[…\]
함수가 프롬프트 문자열 외부에서 사용되도록 의도된 경우 해당 함수를 출력해서는 안 됩니다. 프롬프트 문자열에 및 를 직접 포함합니다 \[
.\]