我试图获得一个在作业中使用函数的简单工作示例。我已经设法将函数传递到用于工作的脚本块中,但似乎无法获取函数的参数。
# concurrency
$Logx =
{
param(
[parameter(ValueFromPipeline=$true)]
$msg
)
Write-Host ("OUT:"+$msg)
}
# Execution starts here
cls
$colors = @("red","blue","green")
$colors | %{
$scriptBlock =
{
Invoke-Expression -Command $args[1]
Start-Sleep 3
}
Write-Host "Processing: " $_
Start-Job -scriptblock $scriptBlock -args $_, $Logx
}
Get-Job
while(Get-Job -State "Running")
{
write-host "Running..."
Start-Sleep 2
}
# Output
Get-Job | Receive-Job
# Cleanup jobs
Remove-Job *
这是输出:
Processing: red
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
175 Job175 Running True localhost ...
Processing: blue
177 Job177 Running True localhost ...
Processing: green
179 Job179 Running True localhost ...
179 Job179 Running True localhost ...
177 Job177 Running True localhost ...
175 Job175 Running True localhost ...
Running...
Running...
OUT:
OUT:
OUT:
因此,正如输出中的OUT:x3所证明的那样,我的函数被调用了,但我还没有找到任何语法可以让我获得函数的参数。想法?
编辑:
请注意,在Shawn下面的观察和我的回答中,我尝试使用函数作为变量,因为使用传统函数似乎不起作用。如果有一种方法可以实现这一点,我会非常乐意不必将函数作为变量传递。
答案是使用StartJob的initializationscript参数。如果在一个块中定义所有函数并传递该块,则这些函数将可用。
解决方案在此帖子中找到:
如何开始我刚定义的函数的作业?
这是我以前的例子,现在正在工作:
# concurrency
$func = {
function Logx
{
param(
[parameter(ValueFromPipeline=$true)]
$msg
)
Write-Host ("OUT:"+$msg)
}
}
# Execution starts here
cls
$colors = @("red","blue","green")
$colors | %{
$scriptBlock =
{
Logx $args[0]
Start-Sleep 9
}
Write-Host "Processing: " $_
Start-Job -InitializationScript $func -scriptblock $scriptBlock -args $_
}
Get-Job
while(Get-Job -State "Running")
{
write-host "Running..."
Start-Sleep 2
}
# Output
Get-Job | Receive-Job
# Cleanup jobs
Remove-Job *
如果不在函数名称前面加关键字function
,PowerShell就不知道该如何处理它。在编写脚本时,它基本上是一个变量,其中包含一些特殊文本。正如您的输出所示,它只执行在该变量内容中识别的命令:Write-Host "OUT:"
。
使用正确的语法将告诉PowerShell这是一个函数,并且您有需要执行的变量要传递给它:
function Logx
{
param(
[parameter(ValueFromPipeline=$true)]
$msg
)
Write-Host ("OUT:"+$msg)
}
然后,当您在脚本中调用它时,您将只使用Logx
走到这一步。必须用完,稍后再试。PS:在args[1]中通过了什么,我得到了很多红色,
CategoryInfo : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand
这是我迄今为止所做的。
# concurrency
$Logx =
{
param(
[parameter(ValueFromPipeline=$true)]
$msg
)
Write-Host ("OUT:"+$msg)
}
# Execution starts here
cls
$colors = @("red","blue","green")
$colors | %{
& $scriptBlock =
{ Invoke-Expression -Command $args[1]
Start-Sleep 3
}
Write-Host "Processing: " $_
Start-Job -scriptblock $scriptBlock -ArgumentList @($_, $Logx)
}
# Get-Job
while(Get-Job -State "Running")
{
write-host "Running..."
Start-Sleep 2
}
# Output
Get-Job | Receive-Job
# Cleanup jobs
Remove-Job *