Bash 프롬프트 기능에서 비 인쇄 문자를 이스케이프 처리


22

Bash Prompt (PS1 변수)에서 잠재적으로 프롬프트에 텍스트를 추가하는 함수를 호출하고 있습니다. export PS1="\u@\h \$(my_function) \$ "

그러나 프롬프트의 기능에는 기능의 출력 (때로는 빨간색, 때로는 녹색)에 따라 변경되는 ANSI 색상 코드가 포함됩니다. \[PS1 변수에 " "를 추가하면 해당 코드가 비 인쇄로 이스케이프되어야하지만 echo함수에서를 수행하면 " \["이 (가) 프롬프트에 문자 그대로 인쇄됩니다.

bash 프롬프트에서 사용하기 위해 ANSI 색상 코드를 함수에서 어떻게 벗어날 수 있습니까?

답변:


34

의 readline 라이브러리는 받아 \001\002(ASCII의 SOH 및 STX 인쇄 할 수없는 텍스트 구분 기호로). readline 을 사용하는 모든 응용 프로그램에서도 작동합니다 .

에서 lib/readline/display.c:243bash는 소스 코드 :

243 /* Current implementation:
244         \001 (^A) start non-visible characters
245         \002 (^B) end non-visible characters
246    all characters except \001 and \002 (following a \001) are copied to
247    the returned string; all characters except those between \001 and
248    \002 are assumed to be `visible'. */

bash는 특이 \[하고는 \]사실에 번역 \001\002에서 y.tab.c:7640.


참고 : 사용하는 경우 bash는 의를 printf하거나 echo -e, 당신의 텍스트가있는 경우 \001또는 \002즉시 번호 앞에, 당신은 칠 것이다 배쉬 진수 이스케이프 처리 할 때이 한 자리에서 너무 많이 먹는 원인이 버그 - 즉, \00142진수로 해석됩니다 올바른 8 진수 01 (ASCII "42") 대신 014 (ASCII "2")가옵니다. 이러한 이유로 16 진수 버전 \x01\x02사용하십시오.


그렇습니다! echo -e "\001\e[31m\002RED"예상대로 작동합니다. 감사!
MidnightLightning

답을 부활 시켜서 죄송하지만 dash / ash / sh에서 이에 상응하는 것은 무엇입니까?
Hosh Sadiq 2016 년

@Hosh 그들은 readline에 사용하는 경우 \001\002작동합니다. 그렇지 않으면 확실하지 않습니다. 예를 들어 대시는 확실히 readline을 사용하지 않습니다 .
wjandrea

1

다음은 좋은 답변입니다. \ 001 등이 어디로 가야하는지 알아 내기 위해 더 많은 파기를해야했습니다. 이것이 도움이되기를 바랍니다.

# Color prompt for git
reset=$(tput sgr0)
boldgreen=$(tput setaf 2)$(tput bold)
cyan=$(tput sgr0)$(tput setaf 6)
boldred=$(tput setaf 1)$(tput bold)
boldwhite=$(tput setaf 7)$(tput bold)
boldyellow=$(tput setaf 3)$(tput bold)

PARENCLR=$'\001\e[0;36m\002'
BRANCHCLR=$'\001\e[1;33m\002'

alias branchname="git branch 2>/dev/null | grep '*' | sed 's/* \(.*\)/ ${PARENCLR}(${BRANCHCLR}\1${PARENCLR}\)/'"

GIT_STATUS='$(branchname)'

PROMPT_CHAR="\$"
PS1="\[$boldgreen\]\u\[$cyan\]::\[$boldred\]\h \[$cyan\]{\[$boldwhite\].../\W\[$cyan\]}\[$reset\]$GIT_STATUS\[$reset\]$PROMPT_CHAR "

여기에 설정 한 방식으로 자식 분기 괄호는 자식 분기에있는 경우에만 나타나고 그렇지 않으면 비어 있습니다.


0

를 기반으로 grawity의 대답 , 다음은 ANSI 제어 ASCII의 순서로 묶어야합니다 SOH( ^A)와 STX( ^B동등) \[\]각각을 :

function readline_ANSI_escape() {
  if [[ $# -ge 1 ]]; then
    echo "$*"
  else
    cat  # Read string from STDIN
  fi | \
  perl -pe 's/(?:(?<!\x1)|(?<!\\\[))(\x1b\[[0-9;]*[mG])(?!\x2|\\\])/\x1\1\x2/g'
}

다음과 같이 사용하십시오.

$ echo $'\e[0;1;31mRED' | readline_ANSI_escape

또는:

$ readline_ANSI_escape "$string"

보너스로 기능을 여러 번 실행하면 이미 이스케이프 된 제어 코드를 다시 이스케이프하지 않습니다.


-2

프롬프트에서 사용하려면을 수행해야합니다 \[. 그러나 반향에서 사용하려면을 사용해야 \033[합니다.


흠 ... 프롬프트에서 다음 인쇄 문자를 인쇄하지 않는 것처럼 보이게 한 후 ANSI 명령 앞에 \ 033 [( "\ e [31m") 및 \ 033]을 추가합니다.
MidnightLightning

1
그 후에는 \ 033을하고 싶지 않습니다. \ 033 [31m은 색상을 시작한 후 \ 033 [0m
Wuffers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.