GREEN="\e[1;32m"
RED="\e[1;31m"
NONE="\e[m"
get_exit_status(){
es=$?
if [ $es -eq 0 ]
then
echo -e "${GREEN}${es}${NONE}"
else
echo -e "${RED}${es}${NONE}"
fi
}
get_path(){
#dummy function
echo "PATH"
}
PROMPT_COMMAND='exitStatus=$(get_exit_status)'
다음은 올바른 exitStatus를 제공하지만 색상 변수는 확장되지 않습니다.
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
그러나 아래 중 하나는 색상을 제공하지만 종료 상태는 업데이트되지 않습니다.
PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
이것을하는 올바른 방법은 무엇입니까? exitStatus와 색상이 모두 작동하도록 어떻게 해결할 수 있습니까?
답변
Gilles는 귀하의 주요 문제를 식별했지만 다른 방식으로 설명하려고합니다.
Bash 는 프롬프트에서 변수를 확장 하기 전에 만 특수 프롬프트 이스케이프를 해석 합니다. 즉 , 프롬프트에서 확장 된 변수 를 사용하면 에서 직접 작동하더라도 작동하지 않습니다 .\e
PS1
예를 들어, 이것은 예상대로 작동하고 빨간색 텍스트를 제공합니다.
PS1='\e[1;31m this is in red '
그러나 이것은 \e
프롬프트에 리터럴 을 넣지 않습니다 .
RED='\e[1;31m'
PS1="$RED not in red "
색상 이스케이프를 변수에 저장하려는 경우 ANSI-C 따옴표 ( $'...'
)를 사용하여 리터럴 이스케이프 문자를 변수에 넣을 수 있습니다.
이렇게하려면, 당신은 당신의 정의를 변경할 수 있습니다 GREEN
, RED
그리고 NONE
그 가치는 실제 이스케이프 시퀀스 그래서.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
그렇게 PS1
하면 작은 따옴표가있는 첫 번째 것이 작동해야합니다.
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
그러나 두 번째 문제가 있습니다.
그것을 실행 해보십시오, 다음을 눌러 Up Arrow다음 Home, 당신의 커서를 줄의 처음으로 되돌아 가지 않을 것이다.
이를 해결하려면 색상 이스케이프 시퀀스 PS1
를 포함 \[
하고 \]
주변으로 변경 하십시오.
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
get_exit_status
출력에는 인쇄 (종료 코드)와 비 인쇄 문자 (컬러 코드)가 모두 포함되어 있으며 프롬프트에 올바르게 표시 할 수 없으므로 여기에서 올바르게 사용할 수 없습니다 . 넣으면 \[...\]
인쇄되지 않은 것으로 표시되어 올바르지 않습니다. 적절한 색상 코드 만 인쇄 한 다음 \[...\]
프롬프트에서 둘러싸도록 기능을 변경 해야합니다.
답변
당신이 실행하는 경우 PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
의 PS1
변수로 설정된 ${RED}\h $(get_path) ${exitStatus}${NONE}
경우에만, \h
프롬프트 이스케이프 시퀀스입니다. 프롬프트 순서가 확장 된 후 (yielding ${RED}darkstar $(get_path) ${exitStatus}${NONE}
) 쉘은 변수 확장과 같은 일반적인 확장을 수행합니다. 다음과 같은 프롬프트가 표시됩니다 \e[1;31mdarkstar PATH 0\e[m
. 도중에 아무것도 \e
시퀀스를 실제 이스케이프 문자로 확장하지 않습니다 .
실행 PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
하면 PS1
변수가로 설정됩니다 \e[1;31m\h PATH 0\e[m
. 변수는 RED
, exitStatus
및 NONE
할당시 확장됩니다. 그런 다음 메시지가 세 프롬프트 이스케이프 시퀀스를 포함 ( \e
, \h
, 그리고 \e
다시). 이 단계에서 확장 할 쉘 변수는 없습니다.
색상을 보려면 실제 이스케이프 문자를 포함하는 색상 변수가 필요합니다. 이 방법으로 할 수 있습니다 :
RED=$'\033[1;31m'
NONE=$'\033[m'
PS1='\[${RED}\]\h \w $?\[${NONE}\] '
$'…'
백 슬래시-옥탈 시퀀스 및을 \n
포함하지 않는 등의 일부 백 슬래시 문자 시퀀스를 확장합니다 \e
. 귀하의 프롬프트를 3 가지로 변경했습니다.
\[…\]
색상 변경 명령과 같은 비 인쇄 시퀀스 주위에 사용하십시오 . 그렇지 않으면 bash가 프롬프트의 너비를 알아낼 수 없으므로 디스플레이가 깨집니다.\w
현재 디렉토리를 인쇄하기위한 내장 이스케이프 시퀀스입니다.- 당신이 처음에
$?
없는 경우 프롬프트 에 표시하기 위해 복잡한 일이 필요 하지 않습니다PROMPT_COMMAND
.
답변
시험:
PS1='`exitStatus=$?;if [ $exitStatus -eq 0 ];then echo "\['${GREEN}'\]";else echo "\['${RED}'\]";fi;echo "\h $(get_path) ${exitStatus}${NONE}"`'
답변
여기에 내가 사용한 접근 방식이 있습니다 PROMPT_COMMAND
.
# This function is called from a subshell in $PS1,
# to provide a colourised visual indicator of the exit status of the last run command
__COLOURISE_EXIT_STATUS() {
# uncomment the next line for exit code output after each command, useful for debugging and testing
#printf -- "\nexit code: $1\n" >&2
[[ 0 == "$1" || 130 == "$1" ]] && printf -- "$GREEN" || printf -- "$RED"
}
다음 $PS1
은 다음과 같습니다 :
PS1='# ${debian_chroot:+($debian_chroot)}'"${GREEN}\u${YELLOW}@${DARK_YELLOW}\h${WHITE}:${LIGHT_BLUE}\w${WHITE}\n"'\[$(__COLOURISE_EXIT_STATUS $?)\]# \$'"\[${WHITE}\] "
답변
여기 있습니다 -Ubuntu 및 다른 Linux (Linuxen?)의 Works For Me (TM)입니다.
종료 코드 감지를 설정하는 이유는 .bashrc를 읽기 전에 $PS1
한 호스트에 읽기 전용 $PROMPT_COMMAND
세트가 있기 때문입니다.
답변
의 경우 PROMPT_COMMAND
함수를 정의하고 사용하는 것이 더 깨끗합니다.
prompt_command() {
# ...
}
PROMPT_COMMAND=prompt_command