web-dev-qa-db-ja.com

定義したばかりの関数のジョブを開始するにはどうすればよいですか?

定義したばかりの関数のジョブを開始するにはどうすればよいですか?

function FOO { write-Host "HEY" } Start-Job -ScriptBlock { FOO } |
Receive-Job

Receive-Job: The term 'FOO' is not recognized as the name of cmdlet,
function ,script file or operable program.

私は何をしますか?ありがとう。

18
Alex58

@Shayが指摘しているように、ジョブにはFOOを定義する必要があります。これを行う別の方法は、-InitializationScriptパラメーターを使用してセッションを準備することです。

あなたの例のために:

$functions = {
    function FOO { write-Host "HEY" }
}

Start-Job -InitializationScript $functions -ScriptBlock {FOO}|
    Wait-Job| Receive-Job

これは、異なるジョブに同じ機能を使用する場合に役立ちます。

22
Rynant

@RynantのInitializationScriptの提案は素晴らしいです

(スクリプト)ブロックの目的は、それらを渡すことができるようにすることだと思いました。だから、あなたがそれをどのようにやっているかに応じて、私は行くと言うでしょう:

$FOO = {write-Host "HEY"}

Start-Job -ScriptBlock $FOO | wait-job |Receive-Job

もちろん、スクリプトブロックをパラメータ化することもできます。

$foo = {param($bar) write-Host $bar}

Start-Job -ScriptBlock $foo -ArgumentList "HEY" | wait-job | receive-job
8
manojlds

関数はscriptblock内にある必要があります:

Start-Job -ScriptBlock { function FOO { write-Host "HEY" } ; FOO } | Wait-Job | Receive-Job
4
Shay Levy

@Rynantの回答の改善:

スクリプトの本体で、関数を通常どおりに定義できます。

Function FOO 
{ 
  Write-Host "HEY" 
} 

次に、この定義をスクリプトブロック内でリサイクルします。

$export_functions = [scriptblock]::Create(@"
  Function Foo { $function:FOO }
"@)

(実質的な関数本体がある場合はより意味があります)次に、上記のようにそれらをStart-Jobに渡します。

Start-Job -ScriptBlock {FOO} -InitializationScript $export_functions| Wait-Job | Receive-Job

デバッガーの下でローカルに実行することでジョブをデバッグする方が簡単なので、この方法が好きです。

1
Bob Mortimer

わたしにはできる。

Start-Job -ScriptBlock ${Function:FOO}
0
Alin

少し違うテイク。関数は、変数に割り当てられた単なるスクリプトブロックです。ああ、それはスレッドジョブでなければなりません。 foreach-object-parallelにすることはできません。

$func = { 'hi' } # or
function hi { 'hi' }; $func = $function:hi

start-threadjob { & $using:func } | receive-job -auto -wait

hi
0
js2010