
Я использую пользовательский PS1 для отображения более важной информации в моем терминале, например, нахожусь ли я в каталоге git и чист ли он или нужно зафиксировать изменения. Однако иногда, когда я прокручиваю команды, часть строки терминала исчезает:
@ ~/tests/testing [tests] > grunt
# up arrow, down arrow
@ ~/tests/testing [t
По сути, он ests] >
обрезается, и у меня остается только [t
.
Есть ли какая-то конкретная причина, по которой часть линии обрывается в этой конфигурации PS1?
Вот дополнительная информация:
Моя переменная окружения TERM — xterm-256color
. Вот моя .bash_profile
:
red='\033[0;31m'
yellow='\033[0;32m'
orange='\033[0;33m'
blue='\033[0;34m'
pink='\033[0;35m'
NC='\033[0m'
function is_git {
if git rev-parse --is-inside-work-tree 2>/dev/null; then
return 1
else
return 0
fi
}
function stuff {
if [ $(is_git) ]; then
git_dir="$(git rev-parse --git-dir 2>/dev/null)"
if [ -z "$(ls -A ${git_dir}/refs/heads )" ]; then
echo -en " [${orange}init${NC}]"
return
fi
echo -n " ["
if [ $(git status --porcelain 2>/dev/null| wc -l | tr -d ' ') -ne 0 ]; then
echo -en "${red}"
else
echo -en "${blue}"
fi
echo -en "$(git rev-parse --abbrev-ref HEAD)${NC}]"
fi
}
export PS1="@ \w\[\$(stuff)\]\[\$(tput sgr0)\] > "
решение1
Предложение @i_am_root поместить \[
and \]
внутри определения red
and и т.п. хорошее. Однако, согласноэтот, bash обрабатывает только \[
и \]
в PS1
, а не в тексте, включенном в PS1
. $()
Поэтому используйте \001
и \002
(или \x01
и \x02
) внутри red
и т. п. вместо \[
и \]
.
Примечание: поэтот ответ, только управляющие коды должны быть в \001
и \002
. Текст, который будет виден пользователю, должен находиться за пределами \001
и , \002
чтобы bash знал, что он занимает место на экране, и мог учесть это при перерисовке.
решение2
Цветовые коды Bash, экранированные символы, назначения и т. п. быстро сбивают с толку.
Попробуйте этот пример кода, который заменяет echo
команды путем добавления к PS1
переменной.
red='\[\033[0;31m\]'
yellow='\[\033[0;32m\]'
orange='\[\033[0;33m\]'
blue='\[\033[0;34m\]'
pink='\[\033[0;35m\]'
NC='\[\033[0m\]'
export PS1="@ \w"
function is_git {
if git rev-parse --is-inside-work-tree 2>/dev/null; then
return 1
else
return 0
fi
}
function stuff {
if [ $(is_git) ]; then
git_dir="$(git rev-parse --git-dir 2>/dev/null)"
if [ -z "$(ls -A ${git_dir}/refs/heads )" ]; then
PS1="${PS1} [${orange}init${NC}]"
return
fi
PS1="$PS1 ["
if [ $(git status --porcelain 2>/dev/null| wc -l | tr -d ' ') -ne 0 ]; then
PS1="${PS1}${red}"
else
PS1="${PS1}${blue}"
fi
PS1="${PS1}$(git rev-parse --abbrev-ref HEAD)${NC}]"
fi
}
stuff
PS1="${PS1}$(tput sgr0) > "