在 Bash 中,目录~
具有特殊地位,因为如果当前目录位于 中~
,它会自动缩短。也就是说,中的替换dirs +0
原子显示\w
PS1
$ 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 \$ '