Powershell: передача параметров функциям, хранящимся в переменных
Я пытаюсь получить простой рабочий пример использования функций внутри рабочих мест. Мне удалось передать свою функцию в блок скриптов, используемый для моей работы, но я не могу получить параметры для функции.
# 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 в выводе, вызывается моя функция, но я не нашел никакого синтаксиса, который позволил бы мне получить параметр для функции. Мысли?
РЕДАКТИРОВАТЬ:
Обратите внимание на наблюдение Шона ниже и мой ответ. Я пытался использовать функции в качестве переменных, потому что использование традиционной функции, похоже, не работает. Если есть способ заставить это работать, я был бы более чем рад, если бы не передавал свои функции как переменные.
3 ответа
Ответ заключается в использовании параметра initializationscript в Start-Job. Если вы определите все свои функции в блоке и передадите блок, они станут доступными.
Решение было найдено в этом посте:
Как начать задание функции, которую я только что определил?
Вот мой предыдущий пример, теперь работающий:
# 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 *