Powershell - 在输出特定字符串时终止命令
Powershell - terminate command when it outputs a certain string
我在 PowerShell 中有一个命令 运行ning,它会莫名其妙地出错(每当网络连接饱和时,它就会出错)
出错后,它将不再按预期运行,而是继续运行。错误也不会打印为错误,就像标准文本一样。
我想让命令 运行ning 在一个循环中检测它何时出错,然后终止它,然后重新启动它,但是我一直找不到任何关于解析命令输出的信息实时。
例如:foo.ps1
每秒输出一个数字,但会随机开始每秒输出一次"ERROR: CONNECTION SATURATED"。我如何创建一个循环来检测、终止进程并重新启动它?
编辑:
command erroring
这就是命令错误的样子。如您所见,错误 (Warning: ring buffer overflow!!!
) 打印为标准输出,而不是错误。
您可以使用trap关键字来检测错误并进行处理,即
function Test {
Write-Host "Doing something..."
trap {
Write-Host "Error found:"
break
}
Write-Host "Code should not reach here"
}
要捕获特定的异常,您可以指定要捕获的内容
...
trap [TheExceptionYouWantToCatch]{
...
}
...
这很奇怪,但是 "select -first 1" 在找到答案时会终止管道。这样只会运行只持续5秒
& { foreach ($i in 1..10) { $i; sleep 1 } } | where { $_ -eq 5 } |
select -first 1
不言而喻,您不能使用标准的 PowerShell 错误处理机制,因为您的命令既不会引发异常也不会写入错误流。因此,您必须在生成时解析命令的输出(即异步)。
运行 命令并异步访问其输出的最简单方法是使用作业。因此,以下脚本应该可以完成您的要求:
param(
# Specifies the commands to run in the job.
[ScriptBlock] $ScriptBlock,
# Specifies the text for which to search in each line of the output.
[string] $Pattern = '^\s*(Warning|Error)',
# Specifies how long to sleep in seconds between output searches.
[int] $Seconds = 1
)
while ($true) {
$job = Start-Job $ScriptBlock
while ($job.State -eq 'Running') {
$output = Receive-Job $job
if ($output -match $Pattern) {
break
}
Start-Sleep $Seconds
}
Stop-Job $job
}
根据您的要求,您可能还想:
- 扩大可接受的集合job states。
- 如果遇到某些特定的作业状态或其他输出模式,则完全终止脚本(即而不重新启动作业)。
我在 PowerShell 中有一个命令 运行ning,它会莫名其妙地出错(每当网络连接饱和时,它就会出错)
出错后,它将不再按预期运行,而是继续运行。错误也不会打印为错误,就像标准文本一样。
我想让命令 运行ning 在一个循环中检测它何时出错,然后终止它,然后重新启动它,但是我一直找不到任何关于解析命令输出的信息实时。
例如:foo.ps1
每秒输出一个数字,但会随机开始每秒输出一次"ERROR: CONNECTION SATURATED"。我如何创建一个循环来检测、终止进程并重新启动它?
编辑:
command erroring
这就是命令错误的样子。如您所见,错误 (Warning: ring buffer overflow!!!
) 打印为标准输出,而不是错误。
您可以使用trap关键字来检测错误并进行处理,即
function Test {
Write-Host "Doing something..."
trap {
Write-Host "Error found:"
break
}
Write-Host "Code should not reach here"
}
要捕获特定的异常,您可以指定要捕获的内容
...
trap [TheExceptionYouWantToCatch]{
...
}
...
这很奇怪,但是 "select -first 1" 在找到答案时会终止管道。这样只会运行只持续5秒
& { foreach ($i in 1..10) { $i; sleep 1 } } | where { $_ -eq 5 } |
select -first 1
不言而喻,您不能使用标准的 PowerShell 错误处理机制,因为您的命令既不会引发异常也不会写入错误流。因此,您必须在生成时解析命令的输出(即异步)。
运行 命令并异步访问其输出的最简单方法是使用作业。因此,以下脚本应该可以完成您的要求:
param(
# Specifies the commands to run in the job.
[ScriptBlock] $ScriptBlock,
# Specifies the text for which to search in each line of the output.
[string] $Pattern = '^\s*(Warning|Error)',
# Specifies how long to sleep in seconds between output searches.
[int] $Seconds = 1
)
while ($true) {
$job = Start-Job $ScriptBlock
while ($job.State -eq 'Running') {
$output = Receive-Job $job
if ($output -match $Pattern) {
break
}
Start-Sleep $Seconds
}
Stop-Job $job
}
根据您的要求,您可能还想:
- 扩大可接受的集合job states。
- 如果遇到某些特定的作业状态或其他输出模式,则完全终止脚本(即而不重新启动作业)。