しばたテックブログ

気分で書いている技術ブログです。

PowerShell 6.0からジョブの実行に & が使える様になります

PowerShell 6.0 Beta.2からジョブの実行方法が拡張され、文の最後*1にアンパサンド(&)を付けることでジョブを起動することができる様になりました。

これはBash等のシェルにある機能と同等のものですが、PowerShellには従来からバックグラウンドで別プロセスのPowerShellを起動するジョブの仕組みがあり、&はその糖衣構文な感じで実装されました。

& によるジョブの起動例

簡単な例として

dir &

と実行するとジョブが起動され以下の様な画面になります。

f:id:stknohg:20171224104740p:plain

この記述は概ね

Start-Job -ScriptBlock {dir}

と一致し、その結果については従来どおりReceive-Jobなどで取り扱うことが可能です。

f:id:stknohg:20171224104758p:plain

& によるジョブ起動の詳細

さきほど 概ね一致 と書きましたが実際には幾つかの点が異なります。

ジョブ起動時のロケーション

&でジョブを起動したときは自動で以下のコマンドが挿入され現在のロケーションをジョブに引き渡す様になっています。

Microsoft.PowerShell.Management\Set-Location -LiteralPath $using:pwd ;

Start-Jobでジョブを起動した場合は何も挿入されません。

f:id:stknohg:20171224104823p:plain

変数の自動引き渡し

&でジョブを起動したときは自動で変数にusingスコープが付与され、その値がジョブに引き渡されます。

例として

$message1 = "Hello"
Write-Output $message1 &

を実行するとジョブで実行されるコマンドは

Microsoft.PowerShell.Management\Set-Location -LiteralPath $using:pwd ; Write-Output ${using:message1}

となり、message1変数にusingスコープが付与されていることが確認できます。
ジョブの結果を見てもちゃんとmessage1変数に値が渡されています。

f:id:stknohg:20171224104858p:plain

Start-Jobでジョブを起動する場合、usingスコープは自分で付与しなければなりません。
以下の様にジョブを実行してしまうとmessage2には何も設定されませんので注意が必要です。

$message2 = "World"
Start-Job -ScriptBlock { Write-Output $message2 }

f:id:stknohg:20171224105058p:plain

最後に

とりあえずこんな感じです。

これまでちょっと実行するのが面倒であったジョブの仕組みですが、&の登場によりより手軽にできる様になったと思います。

補足

本エントリはPowerShell Advent Calendar 2017 22日目の代理投稿になります。

*1:文法上正確にはパイプラインの最後になりますが、ここではわかりやすさのために文の最後と表記します