如何获得"Invoke-Expression"状态,成功还是失败?

vik*_*ata 14 powershell exit-code

Invoke-Expression 将返回被调用的命令的所有文本.

但是,如何获得系统返回值是否已成功执行此命令或失败?在CMD中,我可以%errorlevel%用来获取外部命令执行状态.PowerShell怎么样?

Mat*_*sen 18

通常,您将使用$?检查执行的最后一个语句的状态:

PS C:\> Write-Output 123 | Out-Null; $?
True
PS C:\> Non-ExistingCmdlet 123 | Out-Null; $?
False
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用Invoke-Expression,因为即使传递给的表达式中的语句Invoke-Expression可能失败,Invoke-Expression它自己的调用也会成功(即表达式,尽管无效地调用了无效/非功能)


随着Invoke-Expression你必须使用try:

try {
    Invoke-Expression "Do-ErrorProneAction -Parameter $argument"
} catch {
    # error handling go here, $_ contains the error record
}
Run Code Online (Sandbox Code Playgroud)

或陷阱:

trap {
    # error handling goes here, $_ contains the error record
}
Invoke-Expression "More-ErrorProneActions"
Run Code Online (Sandbox Code Playgroud)

另一种方法是附加";$?"到要调用的表达式:

$Expr  = "Write-Host $SomeValue"
$Expr += ';$?'

$Success = Invoke-Expression $Expr
if(-not $Success){
    # seems to have failed
}
Run Code Online (Sandbox Code Playgroud)

但依赖于没有任何管道输出


Rut*_*uts 10

在PowerShell中,您可以通过检查自动变量来评估执行状态

$?
   Contains True if last operation succeeded and False otherwise.
Run Code Online (Sandbox Code Playgroud)

和/或

$LASTEXITCODE
   Contains the exit code of the last Win32 executable execution.
Run Code Online (Sandbox Code Playgroud)

前者用于PowerShell cmdlet,后者用于外部命令(如%errorlevel%批处理脚本中).

这对你有帮助吗?

  • 无论如何,Invoke-Expression总是将$?设置为$ true,因此在这种情况下$$不会起作用。 (3认同)

cwi*_*rav 8

我找到了一种简单的方法来做到这一点,可以保持 STDOUT 完好无损。

$Expr="MY EXPRESSION"
$Expr += '; $Success=$?'
Invoke-Expression $Expr
Run Code Online (Sandbox Code Playgroud)

成功现在是 True 或 False,并且所有 IO 保持不变。


Kon*_*zik 7

如果调用的可执行文件Invoke-Expression支持它,则可以使用$LASTEXITCODE. 但是,您必须小心变量范围。

function foo 
{
    $global:LASTEXITCODE = 0 # Note the global prefix.
    Invoke-Expression "dotnet build xyz" # xyz is meaningless, to force nonzero exit code.
    Write-Host $LASTEXITCODE
}

foo
Run Code Online (Sandbox Code Playgroud)

如果你运行它,输出将是:

Microsoft (R) Build Engine version 15.9.20+g88f5fadfbe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

MSBUILD : error MSB1009: Project file does not exist.
Switch: xyz
1
Run Code Online (Sandbox Code Playgroud)

观察末尾的 1 表示非零退出代码。

如果您忘记global:前缀,则输出将为 0。我相信这是因为您的函数作用域定义LASTEXITCODE会隐藏全局设置的定义。