質問

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
役に立ちましたか?

解決

呼び出し演算子 '&'この場合は不要です。新しいスコープでコマンドを呼び出すために使用されます。これは通常、文字列またはスクリプトブロックで指定されたコマンドを呼び出すために使用されます。また、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が「この文字列を評価する」のように動作することです。関数。ユーザーが文字列を提供する場合は、特に 慎重に使用してください。 " ri C:\ -r"を提供すれば、あなたの一日はひどくなります。

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

cmd /c $param

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

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

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

他のヒント

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

PS C:\> $cmd = "cmd /c echo foo"
PS C:\> Invoke-expression $cmd
foo

これを行うために私が見つけたもう1つの方法は、コマンドラインの引数の配列を作成し、それをapersand&amp;で使用することでした。オペレーターを呼び出します。このようなもの:

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

& $exe $params;

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

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

&quot;&amp;&quot;が原因で失敗した場合の最後の例文字列を1つの引数として扱うため、&quot; cmd / c echo foo.exe&quot;という名前のプログラムを探しています。 :)

これは動作します:

& $cmd $params

二重引用符の問題については、cmdがPowerShellが入力する引数を引用符で囲むのが気に入らないようです。これを取得します:

cmd "/c echo foo"

だから、/ cの後はすべて正確なコマンドとして扱うと思うので、次のようにします:

echo foo"

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

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

これはcmd / cを使用した成果物だと思います。実行中

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

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

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

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

引数に変数を使用しても同じ結果が発生します:

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top