使用目录树/文件名时的紧凑 bash 提示

使用目录树/文件名时的紧凑 bash 提示

在 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

首先,您可能只想更改\wwith \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标题栏既不包装也不缩写,这可以通过将此处的其他答案之一合并到上述函数中来完成。)

相关内容