about_PSReadLine
简短说明
PSReadLine 在 PowerShell 控制台中提供改进的命令行编辑体验。
自 Windows PowerShell 5.1 中随附的版本以来,PSReadLine 已经进行了多次更新。
- v2.3.5 首先在 PowerShell 7.4.2 和 7.5.0-preview.3 中发布
- v2.3.4 首次在 PowerShell 7.4.0-rc.1 中发布
- v2.2.6 首次在 PowerShell 7.3.0 中发布
- v2.1.0 首先在 PowerShell 7.2.5 中发布
- v2.0.4 首次在 PowerShell 7.0.11 中发布
- v2.0.0 随附在 Windows PowerShell 5.1 中
有关版本差异的详细信息,请参阅 about_PSReadLine_Release_Notes。
详细说明
当前版本的 PSReadLine 可以在 Windows PowerShell 5.1 及更高版本上安装和使用。 对于某些功能,需要运行 PowerShell 7.2 或更高版本。
PSReadLine 为 PowerShell 控制台提供强大的命令行编辑体验。 提供以下功能:
- 命令行语法着色
- 语法错误的直观指示
- 更好的多行体验(编辑和历史记录)
- 可自定义的键绑定
- Cmd 和 Emacs 模式
- 许多配置选项
- Bash 风格补全(Cmd 模式下为可选,Emacs 模式下为默认)
- Emacs yank/kill-ring
- 基于 PowerShell 标记的“单词”移动和删除
PSReadLine 需要 PowerShell 5.1 或更高版本。 PSReadLine 适用于默认的 Windows 控制台主机、Windows 终端和 Visual Studio Code。 它在 Windows PowerShell ISE 中无法正常工作。
可以从 PowerShell 库安装 PSReadLine。 若要在支持的 PowerShell 版本中安装 PSReadLine,请运行以下命令。
Install-Module -Name PSReadLine -AllowClobber -Force
自定义键绑定
PSReadLine 支持使用 Set-PSReadLineKeyHandler
cmdlet 进行自定义键绑定。 例如,大多数自定义键绑定都会调用可绑定函数之一
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
可以将 ScriptBlock 绑定到键。 ScriptBlock 几乎可以执行你所需的任何操作。 一些有用的示例包括
- 编辑命令行
- 打开新窗口(例如帮助)
- 更改目录而不更改命令行
ScriptBlock 接受两个参数:
$key
- 一个 [ConsoleKeyInfo] 对象,它是触发自定义绑定的键。 如果将同一个 ScriptBlock 绑定到多个键,并且需要根据键执行不同的操作,则可以选中$key
。 许多自定义绑定都会忽略此参数。$arg
- 任意参数。 大多数情况下,这是用户从键绑定 DigitArgument 传递的整数参数。 如果绑定不接受参数,则忽略此参数是合理的。
让我们探讨一个将命令行添加到历史记录而不执行该命令行的示例。 当你意识到忘记了执行某项操作,但又不想重新输入已经输入的命令行时,这非常有用。
$parameters = @{
Key = 'Alt+w'
BriefDescription = 'SaveInHistory'
LongDescription = 'Save current line in history but do not execute'
ScriptBlock = {
param($key, $arg) # The arguments are ignored in this example
# GetBufferState gives us the command line (with the cursor position)
$line = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line,
[ref]$cursor)
# AddToHistory saves the line in history, but does not execute it.
[Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($line)
# RevertLine is like pressing Escape.
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
}
}
Set-PSReadLineKeyHandler @parameters
可以在文件 SamplePSReadLineProfile.ps1
中看到更多示例,该文件安装在 PSReadLine 模块文件夹中。
大多数键绑定使用一些帮助器函数来编辑命令行。 这些 API 记录在 about_PSReadLine_Functions 中。
说明
命令历史记录
PSReadLine 维护一个历史记录文件,其中包含从命令行输入的所有命令和数据。 历史记录文件是一个名为 $($host.Name)_history.txt
的文件。 在 Windows 系统上,历史记录文件存储在 $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine
中。
历史记录可能包含敏感数据(包括密码)。 PSReadLine 会尝试筛选掉敏感信息。 任何包含以下字符串的命令行都不会写入历史记录文件。
password
asplaintext
token
apikey
secret
PSReadLine 2.2.0 改进了敏感数据的筛选
- 使用已分析命令行的 PowerShell 抽象语法树 (AST) 来查找敏感数据。
- 使用 SecretManagement 模块中的安全 cmdlet 允许列表来允许将这些命令添加到历史记录中。 允许列表包含:
Get-Secret
Get-SecretInfo
Get-SecretVault
Register-SecretVault
Remove-Secret
Set-SecretInfo
Set-SecretVaultDefault
Test-SecretVault
Unlock-SecretVault
Unregister-SecretVault
例如,允许将以下命令写入历史记录文件:
Get-Secret PSGalleryApiKey -AsPlainText # Get-Secret is in the allowlist
$token = Get-Secret -Name github-token -Vault MySecret
[MyType]::CallRestAPI($token, $url, $args)
$template -f $token
以下命令不会写入历史记录文件:
$token = 'abcd' # Assign expr-value to sensitive variable name.
Set-Secret abc $mySecret # Set-Secret is not in the allowlist.
ConvertTo-SecureString stringValue -AsPlainText # '-AsPlainText' is an alert.
Invoke-WebRequest -Token xxx # Expr-value as argument to '-Token'.
Get-ResultFromTwo -Secret1 (Get-Secret -Name blah -AsPlainText) -Secret2 sdv87ysdfayf798hfasd8f7ha # '-Secret2' has expr-value argument.
如果你不想将其他命令写入历史记录文件,可以使用 Set-PSReadLineOption
cmdlet 的 AddToHistoryHandler 参数。 有关如何使用 AddToHistoryHandler 的示例,请参阅 Set-PSReadLineOption 的示例 7。
PSReadLine 2.3.4 改进了敏感数据的筛选
改进了默认敏感历史记录清理,以允许历史记录包含安全属性访问。
当敏感字符串是属性访问的一部分时:
- 如果此成员访问操作不是分配的一部分,则我们认为它是安全的
- 否则,如果右侧是管道或变量,我们也认为它是安全的
例如,以下用例被视为安全,可以保存到历史记录中。
$a.Secret = Get-Secret -Name github-token -Vault MySecret
$a.Secret = $secret
$a.Password.Secret | Set-Value
$token = (Get-AzAccessToken -ResourceUrl 'https://app.contoso.com').Token
该版本还改进了敏感历史记录清理,以允许使用 az
、 gcloud
和 kubectl
命令行工具检索令牌。
例如,以下用例被视为安全,可以保存到历史记录中。
kubectl get secrets
kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
kubectl describe secret db-user-pass
az account get-access-token --resource=https://app.contoso.com --query accessToken --output tsv
$env:PGPASS = gcloud auth print-access-token
反馈和参与 PSReadLine
欢迎提交拉取请求或在 GitHub 页上提交反馈。
另请参阅
- PSReadLine 深受 GNU readline 库的影响。