構文

2017-12-27 13 views
0

私のスクリプトは、すべての問題のない外部コマンド実行します:構文

$Target= "X:\Backup 2017-12-27.7z" 
Write-Host "Compressing as $Target..." 
& "C:\Program Files\7-Zip\7z.exe" a "$Target" @C:\Webs\Scripts\include.txt -w 

をしかし、私はさらにスイッチを追加するとき、それは完全に壊れる:

$Target= "X:\Backup 2017-12-27.7z" 
Write-Host "Compressing as $Target..." 
& "C:\Program Files\7-Zip\7z.exe" a "$Target" -spf [email protected]:\Webs\Scripts\include.txt [email protected]:\Webs\Scripts\exclude.txt -w 
7z.exe : ERROR: X:\Backup 2017-12-27.7z 
At C:\Webs\Scripts\backup.ps1:50 char:1 
+ & "C:\Program Files\7-Zip\7z.exe" a "$Target" -spf [email protected]:\Webs\Scripts\include.t ... 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (ERROR: X:\Backup 2017-12-27.7z:String) [], RemoteException 
    + FullyQualifiedErrorId : NativeCommandError 

X:\Backup 2017-12-27.7z 
Open ERROR: Can not open the file as [7z] archive 
ERRORS: 
Headers Error 
System ERROR: 
Incorrect function. 

コマンドはcmdから正常に実行されます。 PowerShellの構文は何ですか?どのように修正するのですか?

+2

'EchoArgs'はコマンドをうまく解析します。野生の推測として、スペースの代わりにアンダースコアを使用するとどうなりますか? '$ Target =" X:\ Backup_2017-12-27.7z "'? – vonPryz

+3

同様の問題があることを覚えているようですが、各パラメータを文字列として扱うことで修正しました。 '&$ command $ p1 $ p2 $ p3 $ p4'のようなものです。これはうまくいくはずです、なぜ私はPSがどのようにすべての構文を解釈するのかについて説明することができません。 –

+0

@vonPryz Awesome、それはトリックを行うようです...私はPowerShellの経験はほとんどありません。引数のスペース? –

答えて

2

PowerShellのパラメータ解析では、外部プログラムに渡すパラメータが妨げられることがあります。そのため、PowerShellは、これらのパラメータを、それ自体が処理するはずのパラメータではなく単なる文字列として認識させる必要があります。

$program = 'C:\path\to\your.exe' 
& $program '-a' '-b:foo' 

および/または変数に引数を置く:

$program = 'C:\path\to\your.exe' 
$param1 = '-a' 
$param2 = '-b:foo' 
& $program $param1 $param2 

より良いアプローチは、アレイ内のすべてのパラメータを収集することで、splatいるあなたは、全体の引数の前後に引用符を置くことによってそれを行いますプログラムへの配列:あなたもPowerShelを防ぐために「魔法のパラメータ」(--%)を使用することができV3のPowerShellを皮切り

$program = 'C:\path\to\your.exe' 
$params = '-a', '-b:foo' 
& $program @params 

引数の構文解析から、L:しかし

$program = 'C:\path\to\your.exe' 
& $program --% -a -b:foo 

注意、PowerShellはすべて(変数を含む)ことを意味し、右--%の何を評価しないことは、リテラルとして渡されます。上記のコードで

$program = 'C:\path\to\your.exe' 
& $program --% $foo 

プログラムは、文字列リテラル'$foo'なく変数$fooの値と呼ばれるであろうスニペット。

PowerShell see hereから外部コマンドを実行する方法の詳細については、こちらを参照してください。

0

問題は、$Targetのスペースが原因で発生します。私は他のスイッチの存在に依存して、それがなぜ問題なのか、それともないのか分かりません。 @TimTharrattが指摘しているように、テキストを変数に移動させるという回避策が私の仕事です。注入された変数でも引用符で囲む必要はありません。

$Target= "X:\Backup 2017-12-27.7z" 
Write-Host "Compressing as $Target..." 
$Include = "[email protected]:\Webs\Scripts\include.txt" 
$Exclude = "[email protected]:\Webs\Scripts\exclude.txt" 
& "C:\Program Files\7-Zip\7z.exe" a $Target -spf $Include $Exclude -w 

私は喜んで(つまり、フルCS大きななくても可能です場合)スペースについてのPowerShellの構文を説明し、適切な修正またはを提供する任意の答えを受け入れるだろう。一方、ここでは物事を完了するためのハックです。

+1

'$ Include'と' $ Exclude'変数は不要です。内容をパラメータとして引用すると、コマンドラインで直接動作します。 (一般的なルールは、引数がついた '--'パラメータは引用符で囲む必要があるということです)。 –