代码之家  ›  专栏  ›  技术社区  ›  George Mauer

为什么不能在PowerShell中使用字符串中的参数执行commandlet?

  •  6
  • George Mauer  · 技术社区  · 16 年前

    在WindowsPowerShell中,我尝试将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 回复  |  直到 15 年前
        1
  •  11
  •   Joey Gumbo    16 年前

    从帮助(关于\操作员):

    &  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
    

    与…对比 & , 调用表达式 解析字符串内容,这样就可以在其中放置任何内容,而不仅仅是一个命令。

        2
  •  5
  •   Keith Hill    16 年前

    所有约翰内斯的建议都在现场,但我想让大家知道,在第2版中还有另一个选择。您像以前一样将命令放入字符串中,但将参数放入哈希表中并使用以下方法调用:

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

    这使用了一个新的v2功能,称为splating。这有点像对命令使用响应文件,但将参数放在哈希表中而不是文件中。

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

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

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

        3
  •  2
  •   Community CDub    8 年前

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

    检查过,看起来像是用 . $program $argString & $program $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" 将整个字符串作为命令进行解析并正确执行。

    AS Keith 提到过,Splatting是PowerShell2中的另一个好选项。

    推荐文章