Powershell: パラメータの解析/受け渡し:区切り文字としてコロンを使用した名前付き引数のように見える引用符で囲まれていないトークンは、$ Args / @Argsを介して間接的に渡されると、2つに分割されます。

作成日 2018年03月11日  ·  3コメント  ·  ソース: PowerShell/PowerShell

関連:#6291、#6292、および#4624

https://github.com/PowerShell/PowerShell/issues/6292#issuecomment -371344550からのフォローアップ:

注: -foo:barなどの問題のトークンは、@BrucePayのコメントを参照してください)が、として渡される必要

たまたま-foo.barように見えるトークンも、同様の運命をたどります(#6291を参照)。

これは、_direct_引数を渡すことですでに期待どおりに機能します(例:
echoArgs -foo:bar-foo:barを単一の引数として渡します
)、ただし、 $Argsを渡す/スプラッティングする場合( @Args )はそうではありません。

注:この問題は$Args / @Argsの使用の基本であり、おそらくあまり一般的ではありませんが、PowerShellネイティブコマンドを呼び出すときの使用にも影響します

再現する手順

macOSまたはLinuxで実行します。

function baz {
  bash -c 'for a; do echo $a; done' - $Args   # note: same with <strong i="32">@Args</strong>
}

baz -foo:bar
'---'
baz -foo.bar

予想される行動

-foo:bar
---
-foo.bar

実際の動作

-foo:
bar
---
-foo
.bar

引数は予期せず2つに分かれています。 背景については、リンクされたコメントを参照してください。

環境データ

PowerShell Core v6.0.1 on macOS 10.13.3
PowerShell Core v6.0.1 on Ubuntu 16.04.3 LTS
PowerShell Core v6.0.1 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.674 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Issue-Discussion WG-Language

最も参考になるコメント

私はこの1週間かそこらでこの問題に取り組んでいました。 @Argsでスプラッティングした後、強制スイッチパラメータ値( -foo:$bar )が設定されないように追跡した後、これはあいまいなスコープの問題であるに違いないと思いました。 この方法でスイッチパラメータ値を強制しても期待どおりの動作が得られないことに気付いたときの驚きを想像してみてください。 Powershell 7 Preview 1リリースでもテストしましたが、同じ問題が発生します。 既知の問題である1年以上後にそれが修正されることを願っています...

参考までに、これはバグを示すために作成したテストです。 Powershell 7 Preview1を搭載したServer2016マシン、およびPowershell5.1を搭載したServer2012R2マシンで見ました。

function foo
{
    param(
        [switch]$testArg = $false
    )

    write-host "Test arg value: '$testArg'"
}

function bar
{
    foo <strong i="9">@Args</strong>
}

$testSplat = @{
    testArg = $false
}

write-host "#### Foo tests ####"

foo
foo -testArg:$true
foo -testArg:$false
foo <strong i="10">@testSplat</strong>

write-host "#### Bar tests ####"

bar
bar -testArg:$true
bar -testArg:$false
bar <strong i="11">@testSplat</strong>

全てのコメント3件

注: -foo:barなどの問題のトークンは、名前付きPowerShell引数のように見えます。

私は#6292にコメントで説明したよう@ mklement0、これら_are_は、PowerShellの引数の名前。 いつも。 パラメータのバインドは、コンパイルが完了してからかなり経ってから行われます。 コンパイルされたASTでは、 -foo:のトークンに、ソースコードの後に​​スペースがないことを示すフラグがあります。 NativeCommandParameterBinderは、このAST要素を調べて、フラグが設定されているかどうかを確認し、パラメーターと引数をスペースなしで連結します。 設定されていない場合は、スペースが挿入されます。 これは、引数がリテラルである場合にのみ機能します(つまり、 NativeCommandParameterが引数のASTにアクセスした場合)。 スプラッティングの場合、引数は値であり、リテラル引数ではないため、スペースを取得します。

これを修正する1つの方法は、「NoSpace」トークンプロパティを対応する文字列値のメタデータに伝播することです。 NativeCommandParameterBinderは、arg配列を文字列に変換するときに、このメタデータをチェックできます。 対処すべき他のケース(特に* nix固有のケース)があるかどうかを確認するために、これについてもう少し検討する価値があります。

6492(重複として閉じられたため)は、PowerShell関数(外部プログラムだけでなく)を呼び出すときに@argsプラッティングも壊れていることを示しています。

このシナリオをサポートすることは、おそらくさらに難しいでしょう。なぜなら、ここでの期待は、名前付きパラメーターが元のタイプでそのまま渡されることであるためです。

簡略化した再現は次のとおりです。

function b {
  Param
  (
      [Switch] $p1,
      [int] $p2,
      $rest
  )
  "`$p1: [$p1]"
  "`$p2: [$p2]"
  "`$rest: [$rest]"
}

& { b <strong i="9">@args</strong> } -p1:$false 666
$p1: [True]  # `-p1:` was interpreted as just `-p1`
$p2: [0]      # `$false`, as a separate argument, was coerced to [int] 0
$rest: [666] # what was meant to be the 2nd argument was passed as the 3rd

回避策(および最初に推奨される解決策)は、リレー関数で同じparam()ブロックを定義し、 @PSBoundParametersスプラットすることです。

私はこの1週間かそこらでこの問題に取り組んでいました。 @Argsでスプラッティングした後、強制スイッチパラメータ値( -foo:$bar )が設定されないように追跡した後、これはあいまいなスコープの問題であるに違いないと思いました。 この方法でスイッチパラメータ値を強制しても期待どおりの動作が得られないことに気付いたときの驚きを想像してみてください。 Powershell 7 Preview 1リリースでもテストしましたが、同じ問題が発生します。 既知の問題である1年以上後にそれが修正されることを願っています...

参考までに、これはバグを示すために作成したテストです。 Powershell 7 Preview1を搭載したServer2016マシン、およびPowershell5.1を搭載したServer2012R2マシンで見ました。

function foo
{
    param(
        [switch]$testArg = $false
    )

    write-host "Test arg value: '$testArg'"
}

function bar
{
    foo <strong i="9">@Args</strong>
}

$testSplat = @{
    testArg = $false
}

write-host "#### Foo tests ####"

foo
foo -testArg:$true
foo -testArg:$false
foo <strong i="10">@testSplat</strong>

write-host "#### Bar tests ####"

bar
bar -testArg:$true
bar -testArg:$false
bar <strong i="11">@testSplat</strong>
このページは役に立ちましたか?
0 / 5 - 0 評価