为什么我不能用powershell中的字符串中的参数执行命令行?

时间:2009-08-15 18:04:51

标签: powershell

在windows powershell中,我试图在一个字符串中存储一个move命令,然后执行它。有人能告诉我为什么这不起作用吗?

PS C:\Temp\> dir
    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/14/2009   8:05 PM       2596 sa.csproj
-a---         8/15/2009  10:42 AM          0 test.ps1


PS C:\Temp> $str = "mv sa.csproj sb.csproj"
PS C:\Temp> &$str
The term 'mv sa.csproj sb.csproj' is not recognized as a cmdlet, function, operable program, or script file. Verify the
 term and try again.
At line:1 char:2
+ &$ <<<< str
PS C:\Temp>

存储带参数的任何命令时出现此错误。我如何克服这个限制?

3 个答案:

答案 0 :(得分:11)

来自帮助(about_Operators):

&  Call operator
  Description: Runs a command, script, or script block. Because the call
  operator does not parse, it cannot interpret command parameters.

您可以使用脚本块而不是字符串:

$s = { mv sa.csproj sb.csproj }
& $s

或者您可以使用Invoke-Expression

Invoke-Expression $str

iex $str

&相比,Invoke-Expression 解析字符串内容,因此您可以在其中放置任何内容,而不仅仅是单个命令。

答案 1 :(得分:5)

约翰内斯的所有建议都在现场,但我想让人们意识到在V2中有另一种选择。您将命令放在字符串中,但是您将参数放在哈希表中并使用&amp; e.g:

$cmd = 'mv'
$params = @{Path = 'log.txt'; Destination = 'log.bak'}
&$cmd @params

这使用了一个名为splatting的新V2功能。它有点像为命令使用响应文件,但是您将参数放在哈希表而不是文件中。

注意:您也可以将参数放在一个数组中,该数组将插入“按位置”而不是按名称插入参数,例如:

$cmd = "cpi"
$params = ('log.txt', 'log.bak')
&$cmd @params

它可能不完全符合OP的问题,但这是一个值得了解的技巧。

答案 2 :(得分:2)

在构建参数列表后,我不得不回答一个类似的问题:关于调用外部程序:

  

选中,如果. $program $argString包含多个参数,则使用& $program $argString$argString似乎不起作用。 .&运算符只是直接调用,将​​整个$argString作为单个参数传递。

     

您可以将其更改为[string]$argString并使用$argString += "-aaa `"b b b`"",而不是使用[string[]]$argArray并使用$argArray += @('-aaa', 'b b b'),这将有效,并会根据需要自动转义字符串。

     

您也可以使用$process = [Diagnostics.Process]::Start( $program, $argString )。这样可以更轻松地跟踪执行进度,但更难以检索任何文本输出。

     

或者您可以将所有内容放在字符串中并使用Invoke-Expression "$program $argString",它将整个字符串解析为命令并正确执行。

正如Keith所述,splatting是PowerShell 2中另一个不错的选择。