在 bash 函数中生成 PS1

在 bash 函数中生成 PS1

我想在 bash 命令提示符中显示 Node 的版本。我创建了一个函数来生成 PS1 的该部分。它获取 Node 的主要版本,并根据其数值为其着色。在我的.bash_profile

nv_ps1 () {
  nv_re="v([0-9]+)\.[0-9]+\.[0-9]"
  if [[ $($NVM_BIN/node --version) =~ $nv_re ]]; then
    nv_major=${BASH_REMATCH[1]}
    let nv_color=$nv_major+26
    echo "\[\e[${nv_color}m\]$nv_major\[\e[m\]"
  fi
}

export PS1="[\$(nv_ps1) \[\e[36m\]\t\[\e[m\] \W]\\$ "

不过,函数输出中的转义序列不会被计算,命令提示符最终看起来像这样:

[\[\e[34m\]8\[\e[m\] 08:54:58 ~]$ 

我怎样才能让它发挥作用?

答案1

shell 在运行命令之前评估转义字符NV_PS1。所以这个命令不应该输出转义字符,它们只会逐字显示。 Ascii 代码(颜色)可以通过以下方式输出NV_PS1如果您之前转换过它们,这就是为什么echo -e似乎就足够了。但是\[\]具体针对PS1解释,你无法从你的函数中输出它们。你可以忽略这一点,但你迟早可能会失望。

最简单的解决方案是export PS1="[$(nv_ps1) \[\e[36m\]\t\[\e[m\] \W]\\$ "。因此,转义字符直接存储在PS1任务中。
优点:只评价NV_PS1一次,因此 shell 不会在每次提示时都分叉。
缺点:仅评估NV_PS1一次,所以如果 Node 更新了,当前打开的 shell 提示将不会出现(但你可以source ~/.bashrc)。

如果您确实想让提示保持最新,则必须有两个函数调用export PS1="[\[\$(nv_ps1 color)\]\$(nv_ps1 version)\[\e[m\] \[\e[36m\]\t\[\e[m\] \W]\\$ ",并将其放入您的函数中[[ $1 == color ]] && printf "\e[${nv_color}m" || printf "${nv_major}"

旁注:

  • 不需要导出 PS1。
  • 首选使用局部变量:

    local nv_re="v([0-9]+)\.[0-9]+\.[0-9]"
    local nv_major="${BASH_REMATCH[1]}"
    local nv_color=$((nv_major + 26))
    

答案2

在你的函数中nv_ps1,尝试使用echo -e "\033[${nv_color}m${nv_major}\033[0m",应该会更好

相关内容