Параметр Powershell кажется усеченным значением - PullRequest
1 голос
/ 18 октября 2019

У меня есть скрипт Powershell, который отлично работает в VSCode, но из подсказки 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-й строке вывода, я делаю запись-вывод значения параметра, которое я посылаю, и это правильно. Когда я выполняю 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
...
}

Ответы [ 2 ]

1 голос
/ 18 октября 2019

В Windows PowerShell - по необходимости - перестраивает командную строку для вызова внешних программ .

Примечательно, что большинство внешних программ не понимают одиночные строки в кавычках ('...') через их CLI, поэтому после выполнения собственного анализа PowerShell повторно цитирует результирующие (строковые) аргументы, используя double кавычки ("...") , если он сочтет это необходимым .

К сожалению, это повторное цитирование сломано в нескольких отношениях:

  • Если значение аргумента не содержит пробелов , без , кавычки не применяются. Значения без пробелов, но со специальными символами могут поэтому нарушать команды , особенно когда вызывается другая оболочка , такая как cmd.exe.

    • Например, cmd /c echo 'a&b' прерывается, потому что a&b в конечном итоге передается без кавычек, а & имеет особое значение в cmd.exe
  • ЕслиАргумент имеет встроенных двойных кавычек (" символов), повторное цитирование не автоматически 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" (sic).

  • Аналогично - как и в вашем случае - , если аргумент имеет пробелы и оканчивается на \, то конечный \ равен , а не в результирующем двойномстрока в кавычках, которая нарушает синтаксис аргумента:

    • Например, foo.exe 'a b\' c становится foo.exe "a b\" c - однако большинство программ - включая собственный CLI PowerShell - интерпретируют \" как сбежал " char. вместо закрывающей двойной кавычки, приводящей к неправильной интерпретации аргумента, объединяя его со следующим аргументом, чтобы получить
      a b" c

    • Снова вы должны выполнить экранирование вручную , удвоение \:
      foo.exe 'a b\\' c

      • В качестве альтернативы, если аргумент является путем к каталогу, конечный символ которого \ равеннеобязательно, просто опустите последнее.
0 голосов
/ 18 октября 2019

Get-ChildItem: Невозможно найти путь 'D: \ A', потому что он не существует.

Обратная косая черта (\) здесь выглядит для меня как escape-символ. Пожалуйста, попробуйте с \\

...