0

iex (invoke-expression) と変数を使用して関数を動作させることができません。私が欲しいもの:

function My-Function {

    # code that constructs $command 
    #$command is an arbitrary string that may contain pipes, 
    #variables, command line paramaters, switchs, quoted strings, THE LOT!

    Execute-My-Command-Exactly-As-Though-I-Had-Typed-It-Here $command
}

例えば

function My-Function {
    $command = "`$input | select-string hello"

    iex $command
}

これを行います( . 上記の関数を含むファイルを含めた後)

PS C:\> echo "hello" | My-Function
PS C:\>

しかし、明らかにこれを行う必要があります:

PS C:\> echo "hello" | My-Function

hello


PS C:\>

さらに、実際のコマンド ラインでは、変数 DO が iex によって取得されているようです。

PS C:\> $hello = "hello"
PS C:\>
PS C:\> iex "`$hello | select-string hello"

hello


PS C:\>

私が考えることができる唯一の回避策は、実際に関数をファイルに書き出すことです. それを含めてから呼び出します。しかし、これはひどいです!優れたシェルスクリプト言語の要点は、このメタ的なことを簡単に実行できることです。

解決:

PowerShell ではできませんが、latkin が役立つヒントを提供しています。

4

2 に答える 2

2

歩けるようになる前に走ろうとしていると思います。とはいえ、上記の最初の例を見てみましょう。

function my-function {
    process {
       $_ | select-string "hello"
    }    
}

"hello" | my-function

今、あなたは自分自身にこう言っているかもしれません: これに対して、Invoke-Expression (iex) に関する次のアドバイスを提供します。このような任意のテキストの実行は危険であり、必要になることはめったにありません。一般に、相互運用可能な機能とモジュールの構築についての理解が不足していることを示しています。使い捨てのスクリプトでさえ、IEX を必要とすることはめったにありません。

ですから、そのままにしておくつもりはありませんが、あなたがやろうとしていることについてより高いレベルの視点がなければ、あなたの質問に合理的に答えることはできません. スクリプトまたはスクリプトを実行するためのプロセスを一般化しようとしているようです。そのため、PowerShell でこれを行うためのさまざまなネイティブ メカニズム、つまりドット ソース (.) 演算子と呼び出し (&) 演算子を調べることをお勧めします。

そして最後に、コーヒーを飲みながら座って、Keith Hill の最も優れた無料の電子ブック「Effective Windows PowerShell」を読んでください。

http://rkeithhill.wordpress.com/2009/03/08/effective-windows-powershell-the-free-ebook/

最初の数章は、物事を行う正しい方法を学ぶときに役立ちます。PowerShell の主要なツールである get-command、get-help、get-member について説明し、コマンドモードとモードの違いを理解します。

于 2012-08-28T16:31:01.627 に答える
0

$input非常に奇妙な特殊なケースの自動変数です。との組み合わせはおろか、それに頼るのはまったく悪い考えInvoke-Expressionです。私は$input、関数本体自体のスコープ内にのみあり、動的に呼び出している式のスコープ内で消えると推測しています。

@x0n さんの気持ちに完全に同意します。これは、本当にハッキーで壊れやすく、デバッグが難しく、保守が難しいもののように思えます。目標をよく考えて、問題空間をカプセル化する標準関数と変数をいくつか見つけてください。関数パラメーター、パイプされたパラメーターなどを読んで、言語から適切にサポートされている最適な適切なソリューションを利用できるようにします。

そうは言っても...スクリプトブロックを作成することで、これを回避できます。これにより、外部から引数を渡すことができます。

function My-Function{
    & ([scriptblock]::Create('param($newInput); "Newinput is $newInput"')) $input
}

'piped1', 'piped2' |  my-function
于 2012-08-28T16:59:44.337 に答える