PowerShell历史记录:如何防止重复命令?

22

背景:

现在我有了一种跨会话保存历史记录的方法,因此PowerShell的历史记录对我来说更加有用了。

# Run this every time right before you exit PowerShell
get-history -Count $MaximumHistoryCount | export-clixml $IniFileCmdHistory;

现在,我正在尝试防止PowerShell将重复的命令保存到我的历史记录中。

我尝试使用Get-Unique,但这并不起作用,因为历史记录中的每个命令都是“唯一”的,因为每个命令都有一个不同的ID号码。


Set-PSReadlineOption -HistoryNoDuplicates,但它似乎对我无效。 - imgx64
3个回答

23

Get-Unique 也需要一个排序过的列表,而我假设您可能想保留执行顺序。请尝试使用以下方法。

Get-History -Count 32767 | Group CommandLine | Foreach {$_.Group[0]} |
Export-Clixml "$home\pshist.xml"

这种方法使用Group-Object cmdlet创建唯一的命令桶,然后Foreach-Object块只获取每个桶中的第一个项目。

顺便提一下,如果您想将所有命令保存到历史记录文件中,我会使用极限值32767,除非这是您设置的$MaximumHistoryCount。

顺便提一下,如果您想在退出时自动保存此内容,您可以在2.0上这样做。

Register-EngineEvent PowerShell.Exiting {
  Get-History -Count 32767 | Group CommandLine |
  Foreach {$_.Group[0]} | Export-CliXml "$home\pshist.xml" } -SupportEvent

然后,在加载时要恢复所有内容,您只需要

Import-CliXml "$home\pshist.xml" | Add-History

1
这就是我最初作为答案提供的,但生成的对象不是完整的 HistoryInfo 对象,因此当您尝试使用“Import-Clixml <path> | Add-History”从文件中重新创建历史记录时会出现错误。 - Keith Hill
@Keith 这个命令是防止重复命令还是删除它们?换句话说,当我输入ls 80次时,我需要按80次向上箭头才能返回到“ls”之前的命令吗?还是只需要按两次? - martin jakubik
它不能防止当前会话中的重复命令,但它将从您加载到新会话中的上一个会话的命令中消除它们。 - Keith Hill
3
感谢你的好建议,Keith。不过我想做一个小改动:if (Test-path $MyHistoryFile) { Import-CliXml $MyHistoryFile | Add-History } 这样就避免了在编辑个人资料后第一次启动 PowerShell 时出现的错误信息。 - Michael Sorens
这种方式对我没用。我找到了这个链接,它为我解决了问题:https://software.intel.com/en-us/blogs/2014/06/17/giving-powershell-a-persistent-history-of-commands - mtness
显示剩余3条评论

10

以下命令适用于Windows 10中的PowerShell(在版本1803中测试)。 该选项在此处有文档记录.

Set-PSReadLineOption –HistoryNoDuplicates:$True

实际上,使用以下命令(例如保存在快捷方式中)调用PowerShell会打开一个没有重复历史记录的PowerShell

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command Set-PSReadLineOption –HistoryNoDuplicates:$True

2
只需将 Set-PSReadLineOption -HistoryNoDuplicates 放入我的 $PROFILE 中即可正常工作。不确定早期版本是否存在问题。 - Glenn
使用PowerShell配置文件也可以。它需要创建并更改默认的执行策略,以允许运行脚本。 - divenex

3

虽然与重复内容无直接关系,但同样有用的是,在我的$PROFILE中使用的AddToHistoryHandler脚本块可以将简短且简单的命令从历史记录中排除:

$addToHistoryHandler = {
    Param([string]$line)
    if ($line.Length -le 3) {
        return $false
    }
    if (@("exit","dir","ls","pwd","cd ..").Contains($line.ToLowerInvariant())) {
        return $false
    }
    return $true
}
Set-PSReadlineOption -AddToHistoryHandler $addToHistoryHandler

1
有帮助。谢谢。 - GollyJer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接