在 Ubuntu 14.04 和 的系统中bash
,我的PS1
变量以以下内容结尾:
\u@\h:\w\$
以便提示符显示为
user@machinename:/home/mydirectory$
然而,有时,当前目录的名称很长,或者位于名称很长的目录中,因此提示符看起来像
user@machinename:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name$
这将填满终端中的行,并且光标将转到另一行,这很烦人。
我想获得类似的东西
user@machinename:/home/mydirectory1/...another_long_name$
有没有一种方法可以定义PS1
变量来“包装”和“压缩”目录名称,使其永远不会超过一定数量的字符,从而获得更短的提示?
答案1
首先,您可能只想更改\w
with \W
。这样,只打印当前目录的名称,而不是其整个路径:
terdon@oregano:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name $ PS1="\u@\h:\W \$ "
terdon@oregano:my_actual_directory_with_another_long_name $
如果目录名称本身太长,这可能仍然不够。在这种情况下,您可以使用该PROMPT_COMMAND
变量。这是一个特殊的 bash 变量,其值在显示每个提示之前作为命令执行。因此,如果您将其设置为一个根据当前目录路径的长度设置所需提示的函数,您就可以获得您想要的效果。例如,将这些行添加到您的~/.bashrc
:
get_PS1(){
limit=${1:-20}
if [[ "${#PWD}" -gt "$limit" ]]; then
## Take the first 5 characters of the path
left="${PWD:0:5}"
## ${#PWD} is the length of $PWD. Get the last $limit
## characters of $PWD.
right="${PWD:$((${#PWD}-$limit)):${#PWD}}"
PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] ${left}...${right} \$\[\033[00m\] "
else
PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] "
fi
}
PROMPT_COMMAND=get_PS1
效果如下:
terdon@oregano ~ $ cd /home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name
terdon@oregano /home...th_another_long_name $
答案2
添加字符返回是我对此的主要解决方案
所以我的提示符(还有其他内容,使其更长)如下所示:
您会注意到 $ 作为新行返回
我通过以下方式实现了这一点
HOST='\[\033[02;36m\]\h'; HOST=' '$HOST
TIME='\[\033[01;31m\]\t \[\033[01;32m\]'
LOCATION=' \[\033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`'
PS1=$TIME$USER$HOST$LOCATION'\n\$ '
请注意,即使在单独的行上,超长目录树如
/home/durrantm/Dropbox/96_2013_archive/work/code/ruby__rails
被缩短为
/home/durrantm/Dropbox/_/code/ruby__rails
即“前 3 个目录 /_/ 底部两个目录”,这通常是我关心的
这将确保该行不会因目录树长度而变得太长。如果您总是想要完整的目录树,只需调整 LOCATION,即
LOCATION=' \[\033[01;34m\]`pwd`'
答案3
创建〜/.bash_prompt:
maxlen=36
# set leftlen to zero for printing just the right part of the path
leftlen=19
shortened="..."
# Default PWD
nPWD=${PWD}
if [ ${#nPWD} -gt $maxlen ]; then
offset=$(( ${#nPWD} - $maxlen + $leftlen ))
nPWD="${nPWD:0:$leftlen}${shortened}${nPWD:$offset:$maxlen}"
else
nPWD='\w'
fi
echo "\u@\h:$nPWD\$ "
添加到我的 ~/.bash_profile 中:
function prompt_command {
export PS1=$(~/.bash_prompt)
}
export PROMPT_COMMAND=prompt_command
输出是:
user@machinename:/home/mydirectory1/...another_long_name$
答案4
我使用它,它会换行到多行并按 的长度缩进,user@host
因此它假设当前PS1
实际上是“ \u@\h:\w$
”。它不会截断路径,并且会适应当前的终端宽度。它只分割 上的路径/
,因此它不能优雅地处理很长的目录(但它确实保留了用于选择/复制的空间)。它确保您始终有至少 20 个字符的空间可用于输入。
readonly _PS1="${PS1}" 2>/dev/null
function myprompt()
{
local IFS
local nn nb pbits xpwd="" ww=60 len=0 pp='\\w\$ '
local indent uh="${LOGNAME}@${HOSTNAME//.*/}"
test -n "$COLUMNS" && let ww=$COLUMNS-20 # may be unset at startup
PS1="${_PS1}"
if [ ${#PWD} -ge $ww ]; then
printf -v indent "%${#uh}s%s" " " "> " # indent strlen(user@host)
IFS=/ pbits=( $PWD ); unset IFS
nb=${#pbits[*]}
for ((nn=1; nn<nb; nn++)) {
if [ $(( $len + 1 + ${#pbits[$nn]} )) -gt $ww ]; then
xpwd="${xpwd}/...\n${indent}..."
len=0
fi
xpwd="${xpwd}/${pbits[$nn]}"
let len=len+1+${#pbits[$nn]}
}
# add another newline+indent if the input space is too tight
if (( ( ${#uh} + len ) > ww )); then
printf -v xpwd "${xpwd}\n%${#uh}s" " "
fi
PS1="${PS1/$pp/$xpwd}$ "
fi
}
PROMPT_COMMAND=myprompt
这是通过取出魔法\w
(仅匹配\w$
此)PS1
并将其替换为$PWD
,然后将其包装为纯字符串来实现的。它PS1
每次都会从保存在中的原始值重新计算_PS1
,这意味着“不可见”转义也被保留,我的完整原始提示字符串xterm
和粗体提示:
PS1="\[\033]0;\u@\h:\w\007\]\[$(tput bold)\]\u@\h\[$(tput sgr0)\]:\w$ "
最终结果是 80 列终端:
mr@onomatopoeia:~$ cd /usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace
mr@onomatopoeia:/usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/...
> .../Perf/Trace$ _
这可以从 bash-3.2 开始printf -v var
使用。由于各种复杂性它需要对 的其他变体进行一些调整PS1
。
(路径在xterm标题栏既不包装也不缩写,这可以通过将此处的其他答案之一合并到上述函数中来完成。)