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%批处理脚本中).
这对你有帮助吗?
我找到了一种简单的方法来做到这一点,可以保持 STDOUT 完好无损。
$Expr="MY EXPRESSION"
$Expr += '; $Success=$?'
Invoke-Expression $Expr
Run Code Online (Sandbox Code Playgroud)
成功现在是 True 或 False,并且所有 IO 保持不变。
如果调用的可执行文件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会隐藏全局设置的定义。