7

いくつかのコードを展開するためのPowershellスクリプトを作成しています。プロセスの一部は、RAR.EXEというコマンドライン圧縮ツールを呼び出していくつかのフォルダーをバックアップすることです。

パラメータを動的に構築してから、PowerShellに変数を使用してコマンドを呼び出させようとしていますが、問題が発生しています。動作していません...

次のスクリプトを実行すると、私が話していることがわかります。変数として渡されるパラメーターがマングルされています。コマンドとパラメータ全体を渡すと、悪名高い「コマンドレットとして認識されません...」というメッセージが表示されます。

助けてくれてありがとう!

echo "this should succeed"
& cmd /c echo foo

echo "why does this echo out an additional double quote?"
$param = "/c echo foo"
& cmd "$param"

echo "this does the same"
$param = "/c echo foo"
& cmd $param

echo "escaping the slash doesn't work either..."
$param = "`/c echo foo"
& cmd $param

echo "this fails, but why?"
$cmd = "cmd /c echo foo"
&$cmd
4

6 に答える 6

10

この場合、呼び出し演算子「&」は不要です。これは、新しいスコープでコマンドを呼び出すために使用されます。これは通常、文字列またはスクリプトブロックで指定されたコマンドを呼び出すために使用されます。また、PowerShellスクリプトで作成された変数は、コマンドが終了してスコープがなくなると破棄されるという副次的な利点もあります。

ただし、cmdはEXEであるため、まったく異なるプロセスで実行されます。FWIW、cmd.exeから直接同様の出力を取得します。

> cmd "/c echo foo"
foo"

したがって、最後の余分な引用符はcmd.exeの問題です。通常、PowerShellがコマンドを呼び出すために解析を実行しているときは、コマンドをパラメーターから分離しておく必要があります。

45> & { $foo = "foo" }
46> $foo  # Note that $foo wasn't found - it went away with the scope
47> . { $foo = "foo" } # dotting executes in the current scope
48> $foo 
foo

ここでの注目すべき例外は、Invoke-Expressionが「この文字列を評価する」関数のように動作することです。特にユーザーが文字列を提供する場合は、注意して使用してください。彼らが「riC:\ -r」を提供した場合、あなたの一日は最悪かもしれません。

この場合、他の人が示唆しているように、文字列$param文字列から/cを取り出して、次のように指定します。

cmd /c $param

または、Invoke-Expressionを使用しますが、注意して使用してください。ところで、PowerShellからEXEへの引数の送信に関する問題をデバッグしようとしている場合は、PowerShell Community Extensions(http://pscx.codeplex.com)のechoargsユーティリティを確認してください。とても便利です:

49> $param = "/c echo foo"
50> echoargs $param
Arg 0 is </c echo foo>

これは、cmd.exeが単一の引数として「/cechofoo」を受け取ることを示しています。「/c」は「echofoo」(実行するコマンド)とは別の引数にする必要があります。

于 2009-05-01T18:01:42.307 に答える
8

過去に、実行可能なタイプのコマンドを呼び出そうとしたときに、&call演算子で問題が発生しました。理由がわかりません。ただし、Invoke-Expressionは、常にこのコンテキストで機能するようです。

PS C:\> $cmd = "cmd /c echo foo"
PS C:\> Invoke-expression $cmd
foo
于 2009-05-01T01:15:33.097 に答える
8

これを行うもう1つの方法は、コマンドラインの引数の配列を作成し、それをapersand&call演算子で使用することでした。このようなもの:

$exe = "cmd";
[Array]$params = "/c", "echo", "foo";

& $exe $params;

それは私にとってうまくいきました。

私はもともとこのテクニックをここで見つけました:http: //techstumbler.blogspot.com/2009/12/windows-commands-with-arguments-in.html

于 2009-12-09T18:28:26.763 に答える
3

「&」が文字列を1つの引数として扱うために失敗した場合の最後の例では、「cmd /cechofoo.exe」という名前のプログラムを探しています。:)

これは機能します:

& $cmd $params

二重引用符の問題に関しては、cmdはPowerShellが置く引数の周りの引用符を好まないようです。これを取得します:

cmd "/c echo foo"

したがって、/c以降のすべてを正確なコマンドとして扱うと思います。

echo foo"

一部のコマンドラインプログラムとコマンドラインのファンキーな解析(これが、PowerShellが関数とコマンドレットのこのジョブを引き継ぐ理由です)。cmdの場合、私はこれを提案します:

$param = "echo foo"
& cmd /c $param
于 2009-05-01T02:02:11.800 に答える
0

これはcmd/cを使用した結果だと思います。ランニング

$param = "echo foo"
cmd /c $param

正常に動作します。実際のコード例がない限り、トラブルシューティングは少し難しいです。

于 2009-05-01T00:00:56.227 に答える
0

Argsは、文字列に含まれている場合、異なる方法で処理されます。

PS D:\> echo "1 2 3"
1 2 3
PS D:\> echo 1 2 3
1
2
3

argsに変数を使用した場合も、同じ結果が発生します。

PS D:\> $param = "1 2 3"
PS D:\> echo $param
1 2 3

解決策は、配列を使用することです。

PS D:\> $param = @(1,2,3)
PS D:\> echo $param
1
2
3
于 2012-12-20T00:52:27.690 に答える