Powershell 修改提示符的文字内容和颜色

发表时间 2021-08-24
阅读4分钟

PowerShell 自带的提示符不够美观,影响工作效率。本文介绍一种自定义 PowerShell 命令提示符的方法。

效果展示

作为从 Mac 的 iTerm 迁移到 Windows 的用户,我个人喜欢简单风格的提示符。类似下面这种:

984.png

所以当使用上 PowerShell 后,我自然也希望能延续相同的风格。类似下面这种:

985.png

上图就是我改造 PowerShell 提示符的效果。下面介绍如何实现这种效果。

ps1 文件

ps1 文件类似 linux 的 ~/.profile 文件,在 shell 初始化时会预先执行。在 Powershell 中, ps1 文件的路径保存在 $Profile 变量中,输入 echo $Profile 命令能看到它的绝对路径:

986.png

编辑这个文件,就能规定 Powershell 初始化时的一些行为。

如果是第一次使用 Powershell ,这个文件并不存在,需要你手动创建,输入 notepad $Profile 命令用记事本新建。

987.png

记事本会询问你是否新建,选择"是"。

988.png

这样就得到了一个 ps1 文件,用于自定义 Powershell 的行为。

prompt 函数

Powershell 有一个特殊的函数: prompt 函数,这个函数规定了提示符的内容和外观。默认的 prompt 函数规定了提示符的默认外观,也就是这样:

989.png

我们可以在 上节 中介绍的 ps1 文件中再次自定义 prompt 函数,实现函数的重载,覆盖原有函数的功能。

查看当前使用的 prompt 函数

利用下面的命令可以查看当前使用的 prompt 函数的内容:

(Get-Command Prompt).ScriptBlock

例如:

990.png

图中返回的函数体(“V -")的具体含义,在下节中会介绍。

prompt 函数的基本格式

prompt 函数 的基本格式为:

function Prompt {
  # 编辑你的内容
  return ""
}

如同 上节 中提到,我们只需要在 ps1 文件中重新写 prompt 函数即可。

函数体的最后一个表达式默认就是返回值,所以 return 关键字可以省略。

修改 prompt 函数

通过 prompt 函数的返回值我们就能自定义提示符。返回值可以是固定的字符串,也可以是 powershell 提供的函数。例如:

固定字符串

函数最后一行固定字符串就规定了提示符的内容

function Prompt {
  "R |"
}

效果如下图:

991.png

这中写法就解释了 这一节 中(“V -")函数体的意义。

函数返回值

大部分函数返回值是 Object 类型,并不是字符串格式,用双引号可以强制转换为字符串类型。例如

function Prompt {
    "$(Get-Date)> "
}

上面这个 prompt 函数将提示符显示为当前时间,效果如下:

992.png

使修改生效

当修改并保存 ps1 文件后,还需要执行 ps1 文件才能使最新的修改生效。

类似 linux 环境下的 source 命令。在 Powershell 中,使用点号 . 来重新加载指定的 ps1 文件。由于 $Profile 变量保存了 ps1 文件的绝对路径,所以可以用下面的命令使改动实时生效。

. $Profile

结合下面的例子,我们一起观察修改并生效的全部过程。

首先你在 ps1 文件中写入:

function Prompt {
    "R |"
}

输入 . $Profile 命令生效。再修改 prompt 函数为:

function Prompt {
    "V -"
}

输入 . $Profile 命令生效。完整的效果如下图:

993.png

具体实现

有了上面的知识储备,现在我们可以编写函数,以实现 效果展示 一节中的效果。

步骤思路

为了实现效果展示 一节中的效果,思路如下:

  1. 获取当前路径
  2. 获取用户主目录
  3. 将当前路径中的主目录部分,替换为波浪线(~)
  4. 将替换后的结果加上颜色

下面分步骤来实现。

1. 获取当前路径

使用下面的语句获取当前路径:

$promptString = "$(Get-Location)"

得到类似: C:\Users\name\some\path 这样的字符串。

2. 获取用户主目录

使用下面的语句获取当前路径:

$homepath = $env:userprofile

得到类似这样的: C:\Users\name

用户主目录路径中有反斜杠,不能直接用作正则表达式的 pattern,需要将单斜杠转换为双斜杠:

$pattern = $homepath -replace '\\', '\\'

得到类似这样的: C:\\Users\\name

3. 将当前路径中的主目录部分,替换为波浪线(~)

$promptString = $promptString -replace $pattern, "~"

C:\Users\name\some\path 这样的路径被替换为 ~\some\path

4. 将替换后的结果加上颜色

加上颜色控制符:

return "`e[1;32m" + $promptString + "`e[m "

5. 合成到一起作为函数体

上面的四步 合成到一个函数内,效果如下:

function Prompt {
    $promptString = "$(Get-Location)"
    $homepath = $env:userprofile
    $pattern = $homepath -replace '\\', '\\'
    $promptString = $promptString -replace $pattern, "~"
    return "`e[1;32m" + $promptString + "`e[m "
}

步骤简化后的最终版:

function Prompt {
    $pattern = $env:userprofile -replace '\\', '\\'
    $promptString = "$(Get-Location)" -replace $pattern, "~"
    "`e[1;32m" + $promptString + "`e[m "
}

调试

如果编写的 Prompt 函数有语法错误,Powershell 不会抛出错误,而只会显示为默认的外观。如果想要调试,可以在命令行中直接执行 prompt (对大小写不敏感),下图展示了估计写错命令后的抛错提示:

994.png

显示 git 信息

借着 prompt 函数的灵活编程,我们可以获取 iterm 中的 git 信息,并显示在提示符后方。如下图所示:

996.png

具体的作法另开一篇单独介绍:Powershell 在提示符中显示 git 分支信息

本站是个人博客。除非特别说明,所有文章均系原创,并采用 署名协议 CC-BY 授权。
欢迎转载,惟请保留原文链接:/tech/powershell-prompt-customization/