PowerShell スクリプトでパイプから値を取得する方法
PowerShell スクリプトでパイプから値を取得する方法を試行錯誤してみた。
Cmdletは引数の定義で Parameter(ValueFromPipeline=$True) とすれば、パイプの値を取得できる。
スクリプトも同様に引数の定義を設定でき、パイプ以外の引数はちゃんと処理されるのだが、パイプを受け取る変数をそのまま参照すると、最後の値しか参照できない。
パイプの値は、$input に設定されるので、これを参照するというのがFinal Answer.引数定義と併用できるので、メンドクサイ引数チェックは[CmdletBinding()]で定義すればよろし。
- 引数定義でパイプからも取得できるように設定できる。
[CmdletBinding()]param(Parameter(ValueFromPipeline=$True)[String[]]$test]
でも、$testをそのまま参照しても、最後の値しか参照できない。 - 引数定義のパイプの値は、processブロック内で引数変数を参照すれば、全ての値を参照できることが分かった。でも、functionを定義するとシンタックスエラーになる。
全ての処理をベタに書けと? - processブロックを&{ }の中に書けば、functionを定義できる。
でも、パイプの最後の値しか参照できない!どないせいっちゅーんや!! - パイプの値は、$input に格納される。これを使えばよい。
でも、スクリプト中にパイプを使うと$inputの内容は破棄される。
一時変数に内容をコピーすればOK。コピーは、@($input)。
$inputをそのまま一時変数に代入すると、参照渡しになるので、$inputが破棄されたら一時変数の内容も破棄される。
以下、スクリプトでの試行錯誤の結果。
●$input を使用した方法
PS > get-content ./test1.ps1 #$input に パイプの値が入る。関数内で$inputの内容をパイプで処理すると、中身が消える。\(>Д<)/ #なので、一時変数にコピーを取る。代入だと参照渡しになるので、一時変数の内容も一緒に消える。\(>Д<)/ $tmp = @($input) $tmp | %{ Write-Output $_ } Write-Output "Argment `$input=[${tmp}]" PS > 1..2 | ./test1.ps1 1 2 Argment $input=[1 2]
●NGケース1:引数定義で取得
PS > get-content ./test2.ps1 [CmdletBinding()] param( [Parameter(ValueFromPipeline=$True,Mandatory=$True)] [String[]]$test ) $test | %{ Write-Output $_ } Write-Output "Argment `$test=[${test}]" PS > 1..2 | ./test2.ps1 2 Argment $test=[2]
●OK?ケース:引数定義で取得:processブロックで参照
PS > get-content ./test3.ps1 [CmdletBinding()] param( [Parameter(ValueFromPipeline=$True,Mandatory=$True)] [String[]]$test ) begin{ $test | %{ Write-Output $_ } Write-Output "begin Argment `$test=[${test}]" } process{ $test | %{ Write-Output $_ } Write-Output "process Argment `$test=[${test}]" } end{ $test | %{ Write-Output $_ } Write-Output "end Argment `$test=[${test}]" } PS > 1..2 | ./test3.ps1 begin Argment $test=[] 1 process Argment $test=[1] 2 process Argment $test=[2] 2 end Argment $test=[2]
●NGケース:引数定義で取得:関数定義のため&{ }の中でprocessブロックを定義
PS > get-content ./test3_1.ps1 [CmdletBinding()] param( [Parameter(ValueFromPipeline=$True,Mandatory=$True)] [String[]]$test ) function test() { Write-Output "func-test" } &{ begin{ $test | %{ Write-Output $_ } Write-Output "begin Argment `$test=[${test}]" } process{ $test | %{ Write-Output $_ } Write-Output "process Argment `$test=[${test}]" test } end{ $test | %{ Write-Output $_ } Write-Output "end Argment `$test=[${test}]" } } PS > 1..2 | ./test3_1.ps1 2 begin Argment $test=[2] 2 process Argment $test=[2] func-test 2 end Argment $test=[2]
●OKケース:引数定義と$inputで取得:関数定義のため&{ }の中でprocessブロックを定義:いらないケド
PS > get-content .\test3_2.ps1 [CmdletBinding()] param( [Parameter(ValueFromPipeline=$True,Mandatory=$True)] [String[]]$test ) function func-test() { Write-Output "func-test" } $tmp = @(${input}) &{ begin{ $test | %{ Write-Output "begin:test $_ " } $tmp | %{ Write-Output "begin:input $_ " } Write-Output "begin Argment `$test=[${test}], `$input=[${tmp}]" } process{ $test | %{ Write-Output "process:test $_ " } $tmp | %{ Write-Output "process:input $_ " } Write-Output "process Argment `$test=[${test}], `$input=[${tmp}]" func-test } end{ $test | %{ Write-Output "end:test $_ " } $tmp | %{ Write-Output "end:input $_ " } Write-Output "end Argment `$test=[${test}], `$input=[${tmp}]" } } PS > 1..2 | .\test3_2.ps1 begin:test 2 begin:input 1 begin:input 2 begin Argment $test=[2], $input=[1 2] process:test 2 process:input 1 process:input 2 process Argment $test=[2], $input=[1 2] func-test end:test 2 end:input 1 end:input 2 end Argment $test=[2], $input=[1 2]
« 株:現物売り約定(日立化成、アサヒホールディングス、旭ダイアモンド工業、DMG森精機、MARUWA、OBARA GROUP、KADOKAWA・DOWANGO)未単元株買い約定:(KADOKAWA・DOWANGO) | トップページ | 今週届いた本 »
« 株:現物売り約定(日立化成、アサヒホールディングス、旭ダイアモンド工業、DMG森精機、MARUWA、OBARA GROUP、KADOKAWA・DOWANGO)未単元株買い約定:(KADOKAWA・DOWANGO) | トップページ | 今週届いた本 »
コメント