Bash에서 이러한 시퀀스가 외부 프로세스나 함수의 표준 출력에서 나오는 경우 너비가 0인 시퀀스를 PS1으로 어떻게 인코딩합니까? writes-prompt-sequences-to-stdout
프롬프트에서 여러 색상의 텍스트를 내보내려면 어떻게 해야 합니까 ?
PS1='$( writes-prompt-sequences-to-stdout )'
\[
\]
나는 bash PS1 프롬프트를 작성할 때 bash가 올바른 프롬프트 너비를 계산할 수 있도록 너비가 0인 시퀀스를 래핑해야 한다는 것을 알고 있습니다 .
PS1='\[\e[0;35m\]$ \[\e[00m\]'
\[
\]
bash는 프롬프트의 너비가 2자에 불과하다는 것을 인쇄하지 않고 이해합니다.
이러한 시퀀스를 외부 함수로 어떻게 이동할 수 있나요? 실행하여 stdout에 올바른 바이트 시퀀스를 쓰는 것을 확인할 수 \[\]$ \[\]
있음에도 불구하고 다음은 작동하지 않습니다. 내 프롬프트는 다음과 같습니다 .render-prompt
PS1='$( render-prompt )'
function render-prompt {
printf '\[\e[0;35m\]$ \[\e[00m\]'
}
printf 호출을 PS1로 이동하다일하다:
PS1='$( printf '"'"'\[\e[0;35m\]$ \[\e[00m\]'"'"' )'
아마도 bash가 PS1 문자열을 스캔하고 있는 것 같습니다.실행 전너비가 0인 바이트 수를 계산합니다. 그래서 인쇄되지 않은 [] 시퀀스를 인코딩하여 속이려고 시도했지만 트릭을 올바르게 무시했습니다.
PS1='$( printf '"'"'$$$$$'"'"' '"'"'\[\e[00m\]'"'"' )'
내 질문:
\[
\]
PS1을 통해 호출된 함수나 바이너리의 표준 출력에 시퀀스를 어떻게 작성합니까?
답변1
나는 그것에 대해 생각했다. Bash 특별한 경우 \e
, 및 PS1 \[
. 이스케이프된 바이트, 바이트 , 바이트 로 \]
변환됩니다 . 외부 명령은 표준 출력 에 바이트를 써야 합니다 .\e
\[
1
\]
2
1
2
ASCII에 따르면 "제목 시작"과 "텍스트 시작"을 인코딩합니다.
http://www.columbia.edu/kermit/ascii.html
\
다음은 첫 번째 위치 인수의 이스케이프 문자를 올바른 바이트로 변환하기 위해 printf를 사용하는 작업 예제입니다 .
PS1='$( render-prompt )'
function render-prompt {
printf '\1\033[0;35m\2$ \1\033[00m\2'
}
render-prompt | hexdump -C
00000000 01 1b 5b 30 3b 33 35 6d 02 24 20 01 1b 5b 30 30 |..[0;35m.$ ..[00|
00000010 6d 02 |m.|
00000012
답변2
\1
, \2
및 을 올바르게 계산하셨습니다 \e
. 그러나 시퀀스를 생성하는 더 좋고 더 정확한 방법이 있습니다.
이 printf
명령은 FORMAT을 첫 번째 매개변수로 사용합니다. 이 형식은 후속 매개변수를 사용합니다. 따라서 함수는 다음과 같이 더 잘 작성될 수 있습니다.
render-prompt () { printf "\1%b\2%s\1%b\2" '\e[0;35m' '$ ' '\e[00m'; }
첫 번째 매개변수는 이며 "\1%b\2%s\1%b\2"
, 이것이 형식입니다. 이는 매개변수가 포함된 및 에 대한 \1
적합하고 논리적인 위치입니다 . ( s는 표준 문자열을 나타내는 이스케이프 문자열 입니다 .)\2
%b
%b
\
%s
나머지는 '\e[0;35m'
, '$ '
및 이며 각각 , 및 '\e[00m'
형식에 해당합니다 . s는 앞의 중괄호를 벗어나기 때문에 여기에 넣었습니다.%b
%s
%b
\e
[