我正在编写一个脚本来构造我的 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