仅在非交互式运行时如何从 Powershell 脚本返回退出代码
Posted
技术标签:
【中文标题】仅在非交互式运行时如何从 Powershell 脚本返回退出代码【英文标题】:How to return an exit code from a Powershell script only when run non-interactively 【发布时间】:2010-12-08 19:41:51 【问题描述】:我有很多脚本作为计划任务运行。所以他们会在任何失败时执行$host.setshouldexit(1)
,这会在任务调度程序中显示为返回码。
我还希望能够在调试和测试时以交互方式运行这些脚本。所以$host.setshouldexit()
会终止我的 powershell 或 ISE 会话。
我的问题是:如何检测脚本是否以非交互方式运行?如果是,那么我将使用setshouldexit
,否则它将打印错误代码或非破坏性的东西。 (请注意,我不想使用[environment]::userinteractive
,因为这些脚本并不总是在操作系统认为的非交互式会话中运行。)
有一个 -noninteractive 开关用于计划任务。有什么方法可以从 powershell 查询吗?
【问题讨论】:
【参考方案1】:$Host.SetShouldExit
方法应该不是必需的,并且实际上是不一致的,这取决于您调用脚本的方式。使用关键字 exit
应该可以让您获得退出状态。
使用powershell -F script.ps1
:
exit
- 有效
SetShouldExit
- 忽略
使用powershell -c '.\script.ps1'
:
exit
- 状态减少到 0 或 1,分别代表脚本的成功或失败。
SetShouldExit
- 以正确状态退出,但脚本中的剩余行仍在运行。
使用powershell -c '.\script.ps1; exit $LASTEXITCODE'
[1]:
exit
- 有效
SetShouldExit
- 以状态 == 0 退出,脚本中的剩余行仍在运行。
直接从 powershell 调用 (> .\script.ps1
):
exit
- 有效
SetShouldExit
- 终止调用具有给定退出状态的 powershell 主机
【讨论】:
【参考方案2】:为什么不让它接受一个参数“testing”来设置测试期间的正确行为?你有一个历史缓冲区,所以它几乎不需要再输入了。
【讨论】:
嗯,还不错。我会接受的。【参考方案3】:我有同样的问题。以下对我有用:
# Exit with Return Code when NOT using PowerShell ISE
if ($psise -eq $Null)
$host.SetShouldExit(1)
【讨论】:
交互式 shell 比 ISE 多。【参考方案4】:在找到您的问题后,我进一步解决了这个问题并找到了$MyInvocation.MyCommand.Name
。这在命令解释器和 ISE 命令解释器中都是 False。当一个脚本(我的是jest.ps1
)只包含以下行时:Write-Host $MyInvocation.MyCommand.Name
从 cmd.exe 调用 powershell.exe 运行为:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -NoExit -NonInteractive -NoProfile -File "M:\WindowsPowerShell\Jest.ps1"
输出很简单:
Jest.ps1
【讨论】:
还有,顺便说一句,谢谢你使用 $host.SetShouldExit(1) 的例子! 内联代码用反引号(`)标记,代码块通过每行缩进4个空格来标记。请参阅Editing FAQ。【参考方案5】:检查 $Host.Name。如果您的脚本在 IDE 之外运行,它将返回值 ConsoleHost
。否则它将返回对 IDE 的引用,例如 Windows PowerShell ISE Host
或 PowerGUIScriptEditorHost
。
我必须使用SetShouldExit
,因为运行我的脚本的调度程序通常会忽略其他指示失败的方法。当$Host.Name
为ConsoleHost
时,我添加了一个函数以允许SetShouldExit
。它在测试过程中节省了大量的 IDE 崩溃。
【讨论】:
当脚本作为作业运行时,$Host.Name 等于“ServerRemoteHost”(在 PS v5 上测试)。【参考方案6】:这直接回答了发布者关于是否可以查询powershell控制台是否使用-NonInteractive开关启动的问题。
Function Test-IsPowerShellConsoleNonInteractive [Boolean]([Environment]::GetCommandLineArgs() -Match '-NonInteractive')
$IsPSConsoleNonInteractive = Test-IsPowerShellConsoleNonInteractive
If ($IsPSConsoleNonInteractive) $Host.SetShouldExit(2)
【讨论】:
以上是关于仅在非交互式运行时如何从 Powershell 脚本返回退出代码的主要内容,如果未能解决你的问题,请参考以下文章
本地化应用程序仅在非基本语言上崩溃,并且仅在未使用Xcode运行时崩溃
我的 PowerShell 脚本仅在从 ISE 运行时才有效
OctoberCMS - 如何使可折叠列表默认仅在非移动设备上处于活动状态