![bash: 프롬프트가 시각적으로 깨졌습니다.](https://linux55.com/image/5303/bash%3A%20%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8%EA%B0%80%20%EC%8B%9C%EA%B0%81%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EA%B9%A8%EC%A1%8C%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
내 구성의 아이디어 PS1
는 Mercurial 또는 Git 저장소 상태, 명령 실행 시간 등과 같은 일부 확장 정보를 표시하는 것입니다. 프롬프트는 한 줄에 들어갈 수 없을 만큼 많은 문자를 생성하므로 두 줄로 분할됩니다. 내가 가진 것은 다음과 같습니다 PS1
( .bashrc
여기에 전체 소스 코드가 필요한지 확실하지 않음).
function prompt_status {
local color_app="\e[1;38;5;214m"
local color_branch="\e[1;38;5;32m"
local color_revision="\e[0;38;5;64m"
if git rev-parse --is-inside-work-tree &> /dev/null; then
local branch="$(git rev-parse --abbrev-ref HEAD | tr -d '\n')"
local revision="$(git rev-parse HEAD | tr -d '\n')"
echo -ne $color_app"git "$color_branch"$branch "$color_revision"($revision)"
elif hg status &> /dev/null; then
local branch="$(hg branch | tr -d '\n')"
local revision_number="$(hg identify -n | tr -d '\n')"
local revision="$(hg parent --template '{node}' | tr -d '\n')"
echo -ne $color_app"hg "$color_branch"$branch "$color_revision"($revision_number:$revision)"
else
return
fi
echo -e " \e[0m"
}
function prompt_return_value {
RET=$?
if [[ $RET -eq 0 ]]; then
echo -ne "" #echo -ne "\e[32m$RET\e[0m"
else
echo -ne "\e[1;37;41m$RET\e[0m "
fi
}
function timer_start {
timer=${timer:-$SECONDS}
}
function timer_stop {
seconds_elapsed=$(($SECONDS - $timer))
unset timer
}
function prompt_seconds_elapsed {
local c;
local t=${seconds_elapsed}s
if [ $seconds_elapsed -ge 60 ]; then
c=196
t=$(format_seconds $seconds_elapsed)
elif [ $seconds_elapsed -ge 20 ]; then
c=214
elif [ $seconds_elapsed -ge 10 ]; then
c=100
elif [ $seconds_elapsed -ge 5 ]; then
c=34
elif [ $seconds_elapsed -ge 1 ]; then
c=22
else
return
fi
echo -ne "\e[0;38;5;${c}m${t} \e[0m"
}
function format_seconds {
((h=${1}/3600))
((m=(${1}%3600)/60))
((s=${1}%60))
printf "%02d:%02d:%02d\n" $h $m $s
}
trap 'timer_start' DEBUG
PROMPT_COMMAND=timer_stop
export PS1="\n\e[1;38;5;106m\u@\h \e[0;38;5;136m\w\[\e[0m\]\n\$(prompt_return_value)\$(prompt_seconds_elapsed)\$(prompt_status)\$ "
문제는 터미널 창 너비가 더 작을 때 프롬프트가 깨져 보인다는 것입니다. 이것이 내가 80열에서 얻은 내용입니다:
username@some-very-long-hostname ~/tmp/d
06a14b06cac) $ 9866c9d0d26d2b27063a89ee1c330
두 번째 줄을 감싸는 것과 마찬가지로 완전한 혼란을 야기합니다(가운데에 있는 $ 기호 참조). 더 큰 터미널 열 번호(예: 120)의 경우 거의 완벽하게 작동합니다.
username@some-very-long-hostname ~/tmp/d
hg default (0:69866c9d0d26d2b27063a89ee1c3306a14b06cac) $
또한 터미널 줄 끝에 더 많은 텍스트를 추가하면 위에서 80열에서 설명한 것과 매우 유사한 효과가 발생한다는 사실도 확인했습니다. 문제는 bash
새 줄이 잘못 처리되고 있거나 "너무 길다"는 것입니다 PS1
.
감사해요.
고쳐 쓰다
이 질문은 정확하게 중복된 질문이 아닙니다.기록 검색 시 bash 프롬프트에 문제가 발생하는 이유는 무엇입니까?. @AdamKatz와 논의한 결과 길이가 0인 출력이 이스케이프 \[
되고 ']
문자 그대로 문자열에 입력될 때만 작동하는 것으로 보이지만 PS1
함수에서 반환할 때는 작동하지 않는 것 같아 터미널에서 이스케이프되지 않은 결과가 발생합니다.
답변1
여러 줄 프롬프트(새 줄을 줄바꿈할 때의 명령 프롬프트 포함)의 경우 다음이 필요합니다.색상 코드를 이스케이프된 대괄호로 묶습니다.(좋다 \[$color\]
).
이 예는 녹색이었다 user@hostname:workingdir $
가 무색으로 돌아갑니다.
PS1='\[\e[1;32m\]\u@\h:\w \$\[\e[0;0m\]'
텍스트가 보이 \[
거나 [
프롬프트에 나타나면 아마도 프롬프트 확장으로 해석되기 전에 에서 로 확장되었을 것입니다 \[
. [
이 경우 \001
계속 \[
노력 \002
하면 \]
잘 될 것입니다. 운이 좋지 않다면 \e
한번 시도해 보십시오 \033
. 이러한 8진수 코드는 통과하기 때문에 포팅하기가 더 쉽습니다(유사한 프로그램은 sed
이를 이스케이프하거나 해석하려고 시도하지 않습니다).