Powershell start-job -scriptblock не может распознать функцию, определенную в том же файле?
У меня есть следующий код.
function createZip
{
Param ([String]$source, [String]$zipfile)
Process { echo "zip: $source`n --> $zipfile" }
}
try {
Start-Job -ScriptBlock { createZip "abd" "acd" }
}
catch {
$_ | fl * -force
}
Get-Job | Wait-Job
Get-Job | receive-job
Get-Job | Remove-Job
Однако script возвращает следующую ошибку.
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
309 Job309 Running True localhost createZip "a...
309 Job309 Failed False localhost createZip "a...
Receive-Job : The term 'createZip' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:17 char:22
+ Get-Job | receive-job <<<<
+ CategoryInfo : ObjectNotFound: (function:createZip:String) [Receive-Job], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Кажется, имя функции не может быть распознано внутри блока script start-job
. Я тоже пробовал function:createZip
.
Ответы
Ответ 1
Start-Job
фактически закручивает еще один экземпляр PowerShell.exe, который не имеет вашей функции createZip. Вам нужно включить все это в блок script:
$createZip = {
param ([String]$source, [String]$zipfile)
Process { echo "zip: $source`n --> $zipfile" }
}
Start-Job -ScriptBlock $createZip -ArgumentList "abd", "acd"
Пример возврата сообщения об ошибке из фонового задания:
$createZip = {
param ([String] $source, [String] $zipfile)
$output = & zip.exe $source $zipfile 2>&1
if ($LASTEXITCODE -ne 0) {
throw $output
}
}
$job = Start-Job -ScriptBlock $createZip -ArgumentList "abd", "acd"
$job | Wait-Job | Receive-Job
Также обратите внимание, что с помощью throw
объект job State
будет "Failed", поэтому вы можете получить только те задания, которые не удалось: Get-Job -State Failed
.
Ответ 2
Если вы по-прежнему новичок в использовании функции start-job и receive-job и хотите легче отладить вашу функцию, попробуйте эту форму:
$createZip = {
function createzipFunc {
param ([String]$source, [String]$zipfile)
Process { echo "zip: $source`n --> $zipfile" }
}
#other funcs and constants here if wanted...
}
# some secret sauce, this defines the function(s) for us as locals
invoke-expression $createzip
#now test it out without any job plumbing to confuse you
createzipFunc "abd" "acd"
# once debugged, unfortunately this makes calling the function from the job
# slightly harder, but here goes...
Start-Job -initializationScript $createZip -scriptblock {param($a,$b) `
createzipFunc $a $b } -ArgumentList "abc","def"
Все не упростилось из-за того, что я не определял свою функцию как простой фильтр, как у вас, но который я сделал, потому что в конце концов я хотел передать несколько функций в мой Job.
Извините за то, что выкалываете эту тему, но она тоже решила мою проблему и так элегантно. И поэтому мне просто пришлось добавить этот немного соуса, который я написал во время отладки моей работы в PowerShell.