Powershell 参数似乎截断值

Powershell Parameter Seems to Truncate Value

我有一个在 VSCode 中运行良好的 Powershell 脚本,但在 Powershell 提示符下,我遇到了错误。下面是输出。

→ C:\WINDOWS\system32› powershell.exe -file 'D:\Source\Repos\Powershell Scripts\SD-Report-Archive.ps1' -sourcePath 'D:\Archives\' -targetPath 'D:\Archives2\'
D:\Archives\
Get-ChildItem : Cannot find path 'D:\A' because it does not exist.
At D:\Source\Repos\Powershell Scripts\SD-Report-Archive.ps1:25 char:14
+     $files = Get-ChildItem -Recurse -File -Path $sourcePath
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (D:\A:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

正如您在输出的第 2 行看到的那样,我对发送的参数值进行了 Write-Output,它是正确的。当我执行 Get-ChildItem 时,它似乎将值截断为 'D:\A',我不知道为什么。

Param(
    [Parameter(Mandatory = $true)]
    [string]$sourcePath,
    [Parameter(Mandatory = $true)]
    [string]$targetPath
)

function Copy-FilesIntoFolders {
    param()

    Write-Output $sourcePath;

    $files = Get-ChildItem -Path $sourcePath -Recurse -File
...
}

Get-ChildItem : Cannot find path 'D:\A' because it does not exist.

这里的反斜杠 (\) 在我看来像是一个转义字符。请尝试使用 \\

在 Windows 上,PowerShell - 必要 - 重建 命令行以调用外部程序.

值得注意的是,大多数外部程序无法通过其 CLI 理解 引号字符串 ('...'),因此 在执行了自己的解析,PowerShell 重新引用 使用 double 引号 ("...") 生成的(字符串化)参数 如果它认为有必要.

不幸的是,这个重新引用在几个方面 损坏

  • 如果参数值不包含 空格,则应用 no 引号。 没有空格但有特殊字符的值因此可能会中断命令,尤其是在调用另一个 shell 时,例如 cmd.exe .

    • 例如,cmd /c echo 'a&b'中断,因为a&b最终传递没有引号,&在[=12=中有特殊含义]
  • 如果参数有 嵌入 双引号(" 个字符),重新引用 not automatically escape them 用于在语法上正确嵌入 "..." 或不加引号的文字使用:

    • 例如,foo.exe 'Nat "King" Cole' 被翻译成 foo.exe "Nat "King" Cole" - 注意缺少内部 " 字符的转义。 - 当大多数应用程序解析时会产生 不同的 字符串,即 Nat King Cole(无双引号)。

    • 除了 PowerShell 自己的转义要求外,您还必须手动 执行转义:foo.exe 'Nat \"King\" Cole' 或双引号
      foo.exe "Nat \`"King\`" Cole" (原文如此).

  • 同样 - 就像你的情况一样 - 如果参数有空格并以 \ 结尾,那么尾随 \ 不是 在生成的双引号字符串 中转义,这打破了参数语法:

    • 例如,foo.exe 'a b\' c 变为 foo.exe "a b\" c - 然而,大多数程序 - 包括 PowerShell 自己的 CLI - 将 \" 解释为 转义 " 个字符。而不是结束双引号,导致对参数的误解,将其与下一个参数合并导致
      a b" c

    • 你必须再次执行转义手动,通过加倍\
      foo.exe 'a b\' c

      • 或者,如果参数恰好是一个目录路径,其尾随 \ 是可选的,只需省略后者。