开发者

Why does this PowerShell script fail to execute this external command properly?

开发者 https://www.devze.com 2023-02-14 21:06 出处:网络
The following code will output the command string I wish to run: [string] $SourceRepo=\"C:\\inetpub\\wwwroot\\Spyda\\\"

The following code will output the command string I wish to run:

[string] $SourceRepo="C:\inetpub\wwwroot\Spyda\"
[string] $Repo="C:\inetpub\wwwroot\BranchClone\"
[string] $revstring="--rev `"default`" --rev `"case 1234`""

Write-Output "hg clone $SourceRepo $Repo $revstring"

Which gives

hg clone C:\inetpub\wwwroot\Spyda\ C:\inetpub\wwwroot\BranchClone\ --rev "default" --rev "case 1234"

If I run that from a pow开发者_开发知识库ershell prompt, it works, if I try to run the hg clone command from a script using this syntax, it fails:

hg clone $SourceRepo $Repo $revstring

Error given:

hg.exe : hg clone: option --rev default --rev case not recognized
At line:6 char:3
+ hg <<<<  clone $SourceRepo $Repo $revstring
    + CategoryInfo          : NotSpecified: (hg clone: optio... not recognized:String) [], RemoteE 
   xception
    + FullyQualifiedErrorId : NativeCommandError


Try Invoke-Expression

$SourceRepo="C:\inetpub\wwwroot\Spyda\"
$Repo="C:\inetpub\wwwroot\BranchClone\"
$revstring="--rev `"default`" --rev `"case 1234`""

$cmdString = "hg clone $SourceRepo $Repo $revstring"

Invoke-Expression $cmdString


Use the call operator (&) this way:

 & '.\hg' clone $SourceRepo $Repo $revstring


Using EchoArgs.exe from the PowerShell Community Extensions, we can see what arguments hg.exe is receiving:

PS> & ./EchoArgs.exe clone $SourceRepo $Repo $revstring
Arg 0 is <clone>
Arg 1 is <C:\inetpub\wwwroot\Spyda\>
Arg 2 is <C:\inetpub\wwwroot\BranchClone\>
Arg 3 is <--rev default --rev case>
Arg 4 is <1234>

What happens is that powershell resolves the call to a native application, so it automatically uses quotes to escape variable arguments containing spaces, such as $revstring.

Instead of pre-quoting our arguments, we can take advantage of this escaping by simply building up an array of the distinct values we want to use:

PS> $hgArgs = @('clone',$SourceRepo,$Repo,'--rev','default','--rev','case 1234')
PS> & ./EchoArgs.exe $hgArgs
Arg 0 is <clone>
Arg 1 is <C:\inetpub\wwwroot\Spyda\>
Arg 2 is <C:\inetpub\wwwroot\BranchClone\>
Arg 3 is <--rev>
Arg 4 is <default>
Arg 5 is <--rev>
Arg 6 is <case 1234>
0

精彩评论

暂无评论...
验证码 换一张
取 消