PS1R 未正确对齐

PS1R 未正确对齐

我正在编写一个脚本来构造我的 bash 提示符,但右侧提示符在右侧的最末尾打印了一个额外的字符(该字符属于提示符左侧的开头)。请问这个问题的解决方案是什么?感谢您提供的任何意见;代码如下:

        !/bin/bash

        function LeftRightNewlinePrompt {

        local SAVE='\x1b[s'
        local RESTORE='\x1b[u'

        <<COLORS
        export BLACKBG='00;00;00'
        export WHITEFG='ff;ff;ff' # in decimal=255;255;255
        export GRAYBG='41;4a;4c' # in decimal=65;74;76
        export LIGHTGRAYBG='c0;c5;ce' # in decimal=192;197;206
        export BLUEBG='00;5b;96' # in decimal=00;91;150
        export ORANGEFG='ff;a7;00' # in decimal=255;167;00
        export ORANGEBG='ff;a7;00' # in decimal=255;167;00
        export GREENBG='36;80;2d' # in decimal=54;128;45
        COLORS

        # set your RGB colors
        pipe_color='255;255;255'
        pipe_bg_color='65;74;76'
        username_color='0;0;0'
        username_bg_color='192;197;206'
        at_color='255;255;255'
        at_bg_color='65;74;76'
        host_color='255;255;255'
        host_bg_color='00;91;150'
        workingdir_color='255;255;255'
        workingdir_bg_color='54;128;45'
        date_color='00;00;00'
        date_bg_color='255;167;00'
        time_color='255;167;00'
        time_bg_color='00;00;00'
        bar_spaces_bg_color='167;173;186'

        # leave this block alone
        pipe_color_set="\x1b[38;2;${pipe_color}m"
        pipe_bg_color_set="\x1b[48;2;${pipe_bg_color}m"
        username_color_set="\x1b[38;2;${username_color}m"
        username_bg_color_set="\x1b[48;2;${username_bg_color}m"
        at_color_set="\x1b[38;2;${at_color}m"
        at_bg_color_set="\x1b[48;2;${at_bg_color}m"
        host_color_set="\x1b[38;2;${host_color}m"
        host_bg_color_set="\x1b[48;2;${host_bg_color}m"
        workingdir_color_set="\x1b[38;2;${workingdir_color}m"
        workingdir_bg_color_set="\x1b[48;2;${workingdir_bg_color}m"
        date_color_set="\x1b[38;2;${date_color}m"
        date_bg_color_set="\x1b[48;2;${date_bg_color}m"
        time_color_set="\x1b[38;2;${time_color}m"
        time_bg_color_set="\x1b[48;2;${time_bg_color}m"
        color_reset_set='\x1b[0m'
        bar_spaces_bg_color_set="\x1b[48;2;${bar_spaces_bg_color}m"

        # leave this block alone
        pipe=$(printf "${pipe_color_set}")
        pipebg=$(printf "${pipe_bg_color_set}")
        username=$(printf "${username_color_set}")
        usernamebg=$(printf "${username_bg_color_set}")
        at=$(printf "${at_color_set}")
        atbg=$(printf "${at_bg_color_set}")
        host=$(printf "${host_color_set}")
        hostbg=$(printf "${host_bg_color_set}")
        workingdir=$(printf "${workingdir_color_set}")
        workingdirbg=$(printf "${workingdir_bg_color_set}")
        date=$(printf "${date_color_set}")
        datebg=$(printf "${date_bg_color_set}")
        time=$(printf "${time_color_set}")
        timebg=$(printf "${time_bg_color_set}")
        colorreset=$(printf "${color_reset_set}")
        bar_spaces_bg_color=$(printf "${bar_spaces_bg_color_set}")

        export PS1RHSa=$(printf "%([ %F ])T")
        export PS1RHSb=$(printf "%([ %H:%M ])T")

        export PS1RHSa_stripped=$(sed "s,\x1b\[[0-9;]*[a-zA-Z]),,g"         <<<"$PS1RHSa") 
        export PS1RHSb_stripped=$(sed "s,\x1b\[[0-9;]*[a-zA-Z]),,g" <<<"$PS1RHSb")

        export sizeofPS1RHSa=${#PS1RHSa_stripped}
        export sizeofPS1RHSb=${#PS1RHSb_stripped}
        export sizeofPS1RHS=$((sizeofPS1RHSa + sizeofPS1RHSb))

        export PS1='\[${SAVE}\e[${COLUMNS:-$(tput cols)}C\e[${sizeofPS1RHS}D\[${date}${datebg}\]${PS1RHSa}\[${time}${timebg}\]${PS1RHSb}${RESTORE}\[${pipe}${pipebg}\]|\[${username}${usernamebg}\][ \u ]\[${pipe}${pipebg}\]|\[${at}${atbg}\]@\[${pipe}${pipebg}\]|\[${host}${hostbg}\][ \h ]\[${pipe}${pipebg}\]|\[${colorreset}\]'

        }

        LeftRightNewlinePrompt
```[![these prompts should be on same line][1]][1]


ok here's what it looks like right now..


  [1]: https://i.stack.imgur.com/KlIky.jpg

答案1

思考您可能缺少一些\[和/或\]

尝试一下,将 PS1 分成几部分,希望可以提高可读性

PS1=''

# first line
PS1+=$(printf '\[%s\e[%dC\e[%dD\]' "$SAVE" "${COLUMNS:-$(tput cols)}" "$sizeofPS1RHS")
PS1+=$(printf '\[%s%s\]%s'  "$date" "$datebg" "$PS1RHSa")
PS1+=$(printf '\[%s%s\]%s'  "$time" "$timebg" "$PS1RHSb")
PS1+=$(printf '\[%s\]' "$RESTORE")

# second line
PS1+=$(printf '\[%s%s\]|'       "$pipe"     "$pipebg")
PS1+=$(printf '\[%s%s\][ \u ]'  "$username" "$usernamebg")
PS1+=$(printf '\[%s%s\]|'       "$pipe"     "$pipebg")
PS1+=$(printf '\[%s%s\]@'       "$at"       "$atbg")
PS1+=$(printf '\[%s%s\]|'       "$pipe"     "$pipebg")
PS1+=$(printf '\[%s%s\][ \h ]'  "$host"     "$hostbg")
PS1+=$(printf '\[%s%s\]|'       "$pipe"     "$pipebg")
PS1+=$(printf '\[%s\]' "$colorreset")

我有一个类似的提示。它看起来是这样的

˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ bash 5.1 ˙˙ 12:48:03
glennj@raspberrypi:~/src/other/bash (master (clean))
+$
  • 我经常使用多个 shell,并且它们的提示类似,因此我将 shell 的名称和版本放在提示中,以提醒我身在何处。
  • +是 readline vi 模式的模式指示器。它与多行提示符配合使用效果不佳

我有这个

__bash_prompt() {
    local last_status=$1
    local cwd user_host_path
    # shellcheck disable=SC2001
    cwd=$( sed "s,^$HOME,~," <<<"$PWD" )
    # shellcheck disable=SC2154
    user_host_path="${debian_chroot:+($debian_chroot) }$(id -un)@$(hostname -s):$cwd"

    # terminal title
    if (( BASH_VERSINFO[0] > 3 )); then
        echo -ne "\e]0;$user_host_path\a"
    fi

    # prompt is printed to stderr
    {
        # separator and date
        local spaces time dot='˙' dots
        printf -v spaces "%*s" $(($(tput cols) - 22)) ""
        dots=${spaces// /$dot}
        if (( BASH_VERSINFO[0] <= 3 )); then
            time=$(date '+%T')
        else
            printf -v time '%(%T)T' -1
        fi
        printf "%s bash %s ${dot}${dot} %s\n" "$dots" "${BASH_VERSION:0:3}" "$time"

        # exit status of last command
        if ((last_status != 0)); then
            local color_bold='\e[0;1m'
            local color_reset='\e[0m'
            printf "${color_bold}[%d]$color_reset " "$last_status"
        fi

        # user@host, directory, git branch
        local git_status; git_status=$(git_current_branch -s)
        printf '%s\n' "${user_host_path}${git_status:+" ($git_status)"}"
    } >&2
}

# ref: https://stackoverflow.com/questions/1039713/different-bash-prompt-for-different-vi-editing-mode
# a single-line PS1 allows the show-mode-in-prompt inputrc setting to be useful
PROMPT_COMMAND='__bash_prompt $?'
PS1='\$ '

所以我让 PROMPT_COMMAND 完成所有艰苦的工作,而 PS1 只是锦上添花。

答案2

好的,经过多次尝试后,我得到了我想要的(我相信你们中的一些人可以想出一个更优雅的版本:)),所以如果有人试图做同样的事情,这是我的:

#!/bin/bash

function setColors {
local SAVE=$'\[\e[s\]'
local RESTORE=$'\[\e[u\]'
pipe_color=$'\001\e[38;2;255;255;255m\002'
pipe_bg_color=$'\001\e[48;2;65;74;76m\002'
username_color=$'\001\e[38;2;0;0;0m\002'
username_bg_color=$'\001\e[48;2;192;197;206m\002'
at_color=$'\001\e[38;2;255;255;255m\002'
at_bg_color=$'\001\e[48;2;65;74;76m\002'
host_color=$'\001\e[38;2;255;255;255m\002'
host_bg_color=$'\001\e[48;2;00;91;150m\002'
workingdir_color=$'\001\e[38;2;255;255;255m\002'
workingdir_bg_color=$'\001\e[48;2;54;128;45m\002'
date_color=$'\001\e[38;2;0;0;0m\002'
date_bg_color=$'\001\e[48;2;255;167;0m\002'
time_color=$'\001\e[38;2;255;167;0m\002'
time_bg_color=$'\001\e[48;2;0;0;0m\002'
bar_spaces_color=$'\001\e[48;2;167;173;186m\002'
bar_spaces_bg_color=$'\001\e[48;2;167;173;186m\002'
reset_color=$'\001\e[00m\002'
}

setColors

function printBar {
seq -s ' ' 0 $(($COLUMNS-53)) | tr -d '[:digit:]'
printf '${reset_color}'
}


function setPS1 {
shopt -s checkwinsize; (:;:)
resize &>/dev/null
# DATE=$(date +'[%F]')
# TIME=$(date +'[%H:%M:%S]')
PS1R='${pipe_color}${pipe_bg_color}|${date_color}${date_bg_color}$(date +"[%F]")${reset_color}${pipe_color}${pipe_bg_color}|${time_color}${time_bg_color}$(date +"[%H:%M:%S]")${pipe_color}${pipe_bg_color}|${reset_color}'
PS1='${pipe_color}${pipe_bg_color}|${username_color}${username_bg_color}[\u]${pipe_color}${pipe_bg_color}|${at_color}${at_bg_color}@${pipe_color}${pipe_bg_color}|${host_color}${host_bg_color}[\h]${pipe_color}${pipe_bg_color}|${reset_color}'
printf -v PS1 "\033[s%*s\033[u%s%s%s%s" $((COLUMNS+187)) "${PS1R}" "${PS1}" "${bar_spaces_color}${bar_spaces_bg_color}$(printBar)"
}
 
PROMPT_COMMAND=setPS1

相关内容