PowerShell:上次执行结果是否有自动变量?

时间:2013-01-16 03:41:29

标签: powershell

我正在寻找一个与Python交互式shell的“_”变量相当的功能。在PowerShell中我想要这样的东西:

> Get-Something # this returns an object and display it to the output.
# Now I want to assign that object to some variable
> $anObj = ???

10 个答案:

答案 0 :(得分:16)

没有那样的自动变量。

你必须这样做:

$output = Get-Something
$output
$anObj = $output

获取行为

答案 1 :(得分:6)

最后一个需要大部分工作的选项,但IMO会为您提供您所要求的内容:创建将覆盖Out-Default的代理(在管道末尾始终隐式调用,如果您不执行其他操作)

杰弗里·斯诺弗在其中一次PowerShell Deep Dives中做过演示(我认为这是第一次) - 你可以在Dmitry Sotnikov blog找到他使用的脚本(包括上面提到的默认值)。您还可以从中查看video以了解整个概念。

答案 2 :(得分:4)

如前所述,没有内置支持,但这是 简单但次优的PSv3 + 自定义解决方案

注意:


将以下内容添加到您的$PROFILE文件中:

# Store previous command's output in $__
$PSDefaultParameterValues['Out-Default:OutVariable'] = '__'

如何命名变量-例如$__(两个下划线)-但您要提防名称冲突,特别是与$_ 冲突, automatic 变量,它表示在许多上下文中即将出现的输入对象。

这将捕获交互式会话中变量$__中最近执行的命令[产生终端输出]的终端绑定输出,除了< / em>,用于调用Format-*格式化cmdlet的命令明确 , 通过PowerShell全局预设参数默认值的能力-参见Get-Help about_Parameters_Default_Values

-OutVariable是一种common parameter,旨在将cmdlet的/高级函数的输出对象收集到一个变量中,上面的定义将此参数隐式地应用于所有{{1} }调用,每当PowerShell将某些内容输出到终端时,该调用又在后台调用-但是,请注意re Out-Default cmdlet的异常。

注意事项

  • 如前所述,使用格式化cmdlet的命令的输出-Format-*Format-CustomFormat-HexFormat-List或{{1} }-不会被捕获。

    • 尝试用Format-Table修复它是很诱人的,但是,不幸的是,这会收集{em>格式化对象(指令),而不是{中的原始数据 {1}},这是不希望的。 一种不令人满意的解决方法是将Format-Wide输出捕获到一个不同变量中,这不仅需要您考虑需要定位的变量,而且仍然只能看到格式化对象而不是数据,并且由于$PSDefaultParameterValues['Format-*:OutVariable'] = '__' cmdlet涉及到幕后,即使您没有显式使用它们,也将捕获 $__调用的命令的输出两次-一次在Format-*中作为数据,另一个在另一个变量中作为格式化对象。
  • 由于design quirk Format-*始终包含一个数组列表 (类型Format-*),即使前面的命令仅输出单个对象。如有疑问,请使用$__引用单个输出对象。

  • 谨防产生非常大的输出集的命令,因为$__会将它们收集到内存中

  • [System.Collections.ArrayList]仅捕获输出到 terminal 的对象-就像$__[0]在Python中一样;不产生任何输出或$__ / $__数组的命令将保留所有先前的_值。

答案 3 :(得分:3)

您还可以打印命令的结果并使用OutVariable参数捕获输出对象,稍后再使用$ anObj显示变量内容。

Get-Something -OutVariable anObj

答案 4 :(得分:2)

不完全是。 $ _自动值包含管道中的当前对象

管道是将结果从一个cmdlet传递到下一个cmdlet的常用方法,并且cmdlet设置为接受来自管道或管道中对象属性的参数,从而使“最后结果”变量无关紧要

在某些情况下确实需要对“管道”对象进行特定引用,对于那些需要$ _自动值。

以下是其用法示例:Using the Where-Object Cmdlet以及powershell自动变量列表:Chapter 4. PowerShell Automatic Variables

PowerShell中的脚本需要与Python中的编程不同的样式(与Python相同,需要与C ++不同的样式。)

构建Powershell以便广泛使用管道,如果您想将管道分解为更加程序化的逐步结构,则需要将结果保存在命名变量而非自动变量中。

答案 5 :(得分:2)

如何用“r”(Invoke-History的别名)调用最后一个命令并将其包装在括号()中以首先执行它?

是的,重新运行最后一个命令,但在我的用例中,这是迄今为止最简化的解决方案,特别是在我没有意识到我最初需要输出最后一个命令时。

它还可以保持对象结构的完整。

PS C:\Users\user> Get-NetAdapter -InterfaceIndex 3 | Where {$_.State -match "2"}

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Ethernet                  Intel(R) Ethernet Connection I217-LM          3 Up           XX-XX-XX-XX-XX-XX       100 Mbps

PS C:\Users\user> (r) |where {$_.LinkSpeed -eq "100 Mbps"}
Get-NetAdapter -InterfaceIndex 3 | Where {$_.State -match "2"}

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Ethernet                  Intel(R) Ethernet Connection I217-LM          3 Up           XX-XX-XX-XX-XX-XX       100 Mbps

PS C:\Users\user> (r).MacAddress
Get-NetAdapter -InterfaceIndex 3 | Where {$_.State -match "2"}
XX-XX-XX-XX-XX-XX

答案 6 :(得分:0)

使用模块PowerShellCookbook并将Add-ObjectCollector的调用添加到启动脚本

答案 7 :(得分:0)

对于我的特定用例,我正在从PowerShell运行一个批处理文件,我想实时打印该批处理文件的输出并将输出保存到变量中。通过将调用运算符的输出传递到Tee-Object,可以实现此目的:

$args = @('-r', '-a');
& "C:\myFile.bat" $args | Tee-Object -Variable output;
$output | Set-Clipboard;

第一个命令为批处理文件设置参数。第二个命令使用带有我的参数的调用运算符运行批处理文件,并将输出通过管道传递到Tee-Object命令,该命令实时打印调用运算符的输出,还将所有信息保存到新变量称为 output 。最后一条命令只是将$output的内容复制到剪贴板。

Tee-Object还允许将输出保存到文件(Unicode编码)中,如果我需要将文件保存到文件中(除了打印到控制台),我可以在一个管道中将对Tee-Object的多个调用链接在一起。有关更多信息,请参见此链接:

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/tee-object

答案 8 :(得分:0)

对我有用的一种方法是使用Select-Object作为传递来处理命令的输出。例如,我有一个控制台EXE,可将详细输出输出到stderr,将有意义的输出输出到stdout,而我只想捕获最后一行。

$UtilityPath = ""

(UpdateUtility.exe $ArgList 2>&1) | % {
    If ($_ -Is [System.Management.Automation.ErrorRecord]) {
        $_.Exception.Message
    }
    Else {
        $_
        $UtilityPath = $_
    }
}

在Powershell的Error输出流上输出输出的脚本调用方式被认为是一个硬错误,它与PowerShell接收外部应用的stderr输出并转向放入Error输出中。这种包装输出的方法使我可以控制输出的传递方式,以及捕获所需的stdout行。在我看来,这将是一种相当灵活的方法,可让您截取输出并在输出通过时对其进行任何操作。例如:

$CommandOutput = ""

SomeOtherCommand | % {
    $CommandOutput += "$_`r`n"
    $_
}

答案 9 :(得分:0)

这是从Windows Powershell in Action获得的。在$ profile中获取该源,并使$ last包含last命令的输出。它还会通过键入目录名称来更改目录,或者通过键入网站的URL进入浏览器中的网站。它使Out-Default函数可以覆盖Out-Default cmdlet并对其进行调用。我添加了“开始过程$ __ command”行,因此在osx中​​可以访问网站。

import plotly.express as px