缩短相对于基目录的目录名

缩短相对于基目录的目录名

在 Bash 中,目录~具有特殊地位,因为如果当前目录位于 中~,它会自动缩短。也就是说,中的替换dirs +0原子显示\wPS1

$ dirs +0
~/test/directory

代替/home/myname/test/directory

是否可以授予另一个目录此特殊状态?我经常在顶层为$DEV或 的源树中工作$SRC,并且我想以PS1如下方式显示当前目录

$SRC/current/working/directory

而不是(例如)

~/projects/devel/source/current/working/directory

答案1

如果 $PS1 包含文字变量扩展,则每次显示提示时它们都会被延迟扩展。因此,直接的、仅一次替换的方法是使用${var/#search/replacement}将一个前缀替换为另一个前缀:

PS1='\u@\h ${PWD/#"${SRC:-xxx}"/"\$SRC"} \$ '

请注意赋值是如何使用单引号的,因此${PWD...}扩展是逐字包含的,而不是在赋值时扩展的。(在 bash 中默认使用惰性 PS1 扩展,但如果你知道要启用哪个选项,也可以在 zsh 中使用。我不知道。)

使用${SRC:-xxx}而不是仅仅$SRC是为了防止 $SRC 为空或未设置,这是一种愚蠢的保护措施,在这种情况下,您会在任何地方都获得前缀,而不是在任何地方都获得前缀。

稍微复杂的方法是调用自定义函数并让其生成所需的输出:

show_abbrevd_path() {
    # longest prefix should be first
    case $PWD in
        "$SRC/"*)  echo "${PWD/#"$SRC/"/"\$SRC/"}";;
        "$HOME/"*) echo "${PWD/#"$HOME/"/"~/"}";;
        *)         echo "$PWD";;
    esac
}

PS1='\u@\h $(show_abbrevd_path) \$ '

(附言:引文"${PWD/#"$SRC/"/"\$SRC/"}"实际上是嵌套并且没有关闭/重新打开。${…} 就是这么神奇,尽管 SU 的语法高亮器却不这么认为。)

当然,它不一定是一个函数——你也可以使用$(pwd | sed ...)$(perl ...)$(~/bin/fancypwd)——但你创建的进程越多,显示提示符所需的时间就越长,并且 shell感觉从而变得更慢。

就这一点而言,你可以使用通过 $PROMPT_COMMAND 调用函数并获取其全局状态来管理子进程,从而避免 $(…) 子 shell:

make_abbrevd_path() {
    case $PWD in
        "$SRC/"*)  xpwd="${PWD/#"$SRC/"/"\$SRC/"}";;
        "$HOME/"*) xpwd="${PWD/#"$HOME/"/"~/"}";;
        *)         xpwd="$PWD";;
    esac
}

PROMPT_COMMAND='make_abbrevd_path'

PS1='\u@\h $xpwd \$ '

相关内容