我正在努力更好地了解powershell如何处理工作。
这两篇文章都有很多帮助:
但是,使用以下示例脚本,我在调用Receive-Job时收到意外结果。我希望每行都有一个结果,但有时我会看到每行多个结果或额外的空白回车。有关如何仅从每个作业中写出从控制台流入的信息的想法吗?
$loops = 1..10
$jobs = new-object System.Collections.ArrayList
$loops | % {
$jobs.add(
(start-job -ScriptBlock {
param($list)
$list | % {
sleep -seconds (get-random -Maximum 3 -Minimum 1)
write-host "Number is: $_"
}
} -ArgumentList (,$loops))
) | out-null
}
while ($jobs.count -gt 0)
{
if ($jobs -ne $null)
{
$list = $jobs | ? { $_.HasMoreData -eq $true }
$list | % { Receive-Job -Job $_ }
$list2 = $jobs.Clone() | ? { $_.State -eq "Completed" }
$list2 | % {
$jobs.Remove($_) | out-null
}
$list = $null
}
}
输出可以是......
Number is: 1 Number is: 1 Number is: 2
或者有时......
Number is: 1 Number is: 2 Number is: 1Number is: 2 Number is: 1Number is: 2Number is: 2
答案 0 :(得分:3)
你这太过于复杂了。您不需要所有这些循环来手动处理事物。您应该利用可用的cmdlet。这应该达到你想要的基础:
$loops = 1..10
$scriptBlock = {
param($list)
$list | % {
sleep -seconds (get-random -Maximum 3 -Minimum 1)
write-host "Number is: $_"
}
}
$jobs = $loops | % { start-job -ScriptBlock $scriptBlock -ArgumentList (,$loops) }
$jobs | Wait-Job | Receive-Job
然而,这将把所有输出组合在一起,而无需知道什么工作做了什么。而且您使用Write-Host
这一事实意味着您无法实际访问数据,只会将其打印到屏幕上。
如果您想实际存储或处理生成的作业输出,可以执行以下操作:
$loops = 1..10
$scriptBlock = {
param($list)
$list | % {
sleep -seconds (get-random -Maximum 3 -Minimum 1)
"Number is: $_" # don't use write-host, just output the string
}
}
$jobs = $loops | % { start-job -ScriptBlock $scriptBlock -ArgumentList (,$loops) }
$jobs | Wait-Job # wait for all jobs to be complete
$jobs |%{
$output = $_ | Receive-Job
# process $output here, do what you want with it
}