我确信我曾见过有人将提示符的一部分在终端窗口中向右对齐,然后实际光标从第二行开始。我知道我可以在 PS1 中使用“\n”来实现第二行,但我不知道如何将其部分向右对齐。我看到的只是在两个字符串之间添加了空格吗?
答案1
通过在显示提示符之前显示第一行,您可以相当轻松地实现所需的操作。例如,下面\w
在第一行的左侧显示一个提示符,\u@\h
在第一行的右侧显示一个提示符。它利用了$COLUMNS
包含终端宽度的变量和$PROMPT_COMMAND
在 bash 显示提示符之前评估的参数。
print_pre_prompt ()
{
PS1L=$PWD
if [[ $PS1L/ = "$HOME"/* ]]; then PS1L=\~${PS1L#$HOME}; fi
PS1R=$USER@$HOSTNAME
printf "%s%$(($COLUMNS-${#PS1L}))s" "$PS1L" "$PS1R"
}
PROMPT_COMMAND=print_pre_prompt
答案2
根据我在这里找到的信息,我能够找到一种更简单的右对齐解决方案,同时容纳右侧或左侧的可变长度内容,包括对颜色的支持。在此处添加以方便您使用...
颜色注意事项:事实证明,使用\033
逃避方式来支持替代方案(不进行\[\]
分组)是最兼容的,因此值得推荐。
诀窍是先写右侧内容,然后使用回车符 ( \r
) 返回行首并继续在其上覆盖左侧内容,如下所示:
prompt() {
PS1=$(printf "%*s\r%s\n\$ " "$(tput cols)" 'right' 'left')
}
PROMPT_COMMAND=prompt
我在 Mac OS X 上使用tput cols
来检索终端/控制台宽度,因为terminfo
我的$COLUMNS
var 没有填充,但您可以通过提供“ ”或您喜欢的任何其他值来替换中的env
可替换“ ”值。*
%*s
${COLUMNS}
下一个示例用于$RANDOM
生成包含颜色的不同长度的内容,并展示如何提取函数来重构实现为可重用的函数。
function prompt_right() {
echo -e "\033[0;36m$(echo ${RANDOM})\033[0m"
}
function prompt_left() {
echo -e "\033[0;35m${RANDOM}\033[0m"
}
function prompt() {
compensate=11
PS1=$(printf "%*s\r%s\n\$ " "$(($(tput cols)+${compensate}))" "$(prompt_right)" "$(prompt_left)")
}
PROMPT_COMMAND=prompt
由于printf
假设字符串的长度为字符数,因此我们需要补偿渲染颜色所需的字符数,您会发现它总是少于屏幕的末尾,因为没有补偿未打印的 ANSI 字符。颜色所需的字符保持不变,您会发现 printf 也会考虑长度的变化,例如$RANDOM
' 返回的长度,这使我们的右对齐保持完整。
\u
但是,特殊 bash 提示符转义序列(即、\w
、\h
、 )则不是这种情况\t
,因为它们只会记录长度 2,因为 bash 只会在 printf 呈现字符串后,在显示提示符时才转换它们。这不会影响左侧,但最好避免在右侧使用它们。
如果生成的内容长度保持不变,则无关紧要。就像时间\t
选项一样,它将始终在 24 个时间中呈现相同数量的字符(8)。在这些情况下,我们只需要考虑所需的补偿,以适应 2 个字符之间的差异,从而打印时产生 8 个字符。
请记住,您可能需要对\\\
某些转义序列进行三重转义,否则这些转义序列对字符串有意义。如以下示例所示,当前工作目录转义\w
没有其他意义,因此它可以按预期工作,但如果不先对其进行三重转义,则时间\t
(表示制表符)将无法按预期工作。
function prompt_right() {
echo -e "\033[0;36m\\\t\033[0m"
}
function prompt_left() {
echo -e "\033[0;35m\w\033[0m"
}
function prompt() {
compensate=5
PS1=$(printf "%*s\r%s\n\$ " "$(($(tput cols)+${compensate}))" "$(prompt_right)" "$(prompt_left)")
}
PROMPT_COMMAND=prompt
好开心!
答案3
使用printf
with$COLUMNS
效果很好,例如:
printf "%${COLUMNS}s\n" "hello"
对于我来说,这完全是正确的。
答案4
我只是想把我的放在这里。它几乎与 GRML zsh 提示符完全相同(除了 zsh 在新行和退格方面对其提示符的更新稍好一些 - 这在 bash 中是不可能复制的......至少目前非常困难)。
我花了整整三天的时间在这上面(只在运行 arch 的笔记本电脑上进行了测试),所以这里有一个屏幕截图,然后是我 ~/.bashrc 中的内容 :)
警告-有点疯狂
重要的事- 每个^[
(例如^[[34m
)实际上是转义字符(char)27
。我知道的唯一插入方法是输入ctrl+( [v)(即同时按下和[)。vctrl
# grml battery?
GRML_DISPLAY_BATTERY=1
# battery dir
if [ -d /sys/class/power_supply/BAT0 ]; then
_PS1_bat_dir='BAT0';
else
_PS1_bat_dir='BAT1';
fi
# ps1 return and battery
_PS1_ret(){
# should be at beg of line (otherwise more complex stuff needed)
RET=$?;
# battery
if [[ "$GRML_DISPLAY_BATTERY" == "1" ]]; then
if [ -d /sys/class/power_supply/$_PS1_bat_dir ]; then
# linux
STATUS="$( cat /sys/class/power_supply/$_PS1_bat_dir/status )";
if [ "$STATUS" = "Discharging" ]; then
bat=$( printf ' v%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
elif [ "$STATUS" = "Charging" ]; then
bat=$( printf ' ^%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
elif [ "$STATUS" = "Full" ] || [ "$STATUS" = "Unknown" ] && [ "$(cat /sys/class/power_supply/$_PS1_bat_dir/capacity)" -gt "98" ]; then
bat=$( printf ' =%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
else
bat=$( printf ' ?%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
fi;
fi
fi
if [[ "$RET" -ne "0" ]]; then
printf '\001%*s%s\r%s\002%s ' "$(tput cols)" ":( $bat " "^[[0;31;1m" "$RET"
else
printf '\001%*s%s\r\002' "$(tput cols)" "$bat "
fi;
}
_HAS_GIT=$( type 'git' &> /dev/null );
# ps1 git branch
_PS1_git(){
if ! $_HAS_GIT; then
return 1;
fi;
if [ ! "$( git rev-parse --is-inside-git-dir 2> /dev/null )" ]; then
return 2;
fi
branch="$( git symbolic-ref --short -q HEAD 2> /dev/null )"
if [ "$branch" ]; then
printf ' \001%s\002(\001%s\002git\001%s\002)\001%s\002-\001%s\002[\001%s\002%s\001%s\002]\001%s\002' "^[[0;35m" "^[[39m" "^[[35m" "^[[39m" "^[[35m" "^[[32m" "${branch}" "^[[35m" "^[[39m"
fi;
}
# grml PS1 string
PS1="\n\[\e[F\e[0m\]\$(_PS1_ret)\[\e[34;1m\]${debian_chroot:+($debian_chroot)}\u\[\e[0m\]@\h \[\e[01m\]\w\$(_PS1_git) \[\e[0m\]% "
我仍在努力使颜色可配置,但我对现在的颜色很满意。
目前正在修复疯狂的^[
角色和简单的颜色切换:)