Использование обратного апострофа PowerShell для выполнения фрагмента не работает

Когда я запускаю команду обратной кавычки (`) в этом фрагменте:

      Get-WmiObject win32_service | Where-Object { $_.pathname -notlike "C:\windows\*" -and $_.startmode -eq "auto" -and $_.startname -eq "localsystem"} | Select-Object displayname, `
pathname, startmode, startname | Format-List | Out-Host

У меня есть ошибки. Что это за ошибки ?

Во-первых , нажав F8 только в первой строке , я получаю следующее:

Неполный строковый токен. + CategoryInfo: ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId: IncompleteString

Цель : запустить фрагмент и предположить, что ПК автоматически перейдет на следующую строку, поскольку в ней есть символ ` .

Во-вторых , когда я выделяю только первую строку , щелкнув слева от номеров строк, я получаю следующее:

В строке: 1 символ: 170

  • ... to "-and $ _. startname -eq" localsystem "} | Select-Object displayname,`
  •                                                                             ~ Missing expression after ',' > in pipeline element.
    
    • CategoryInfo: ParserError: (:) [], ParentContainsErrorRecordException
    • FullyQualifiedErrorId: MissingExpression

Цель : запустить фрагмент и предположить, что ПК автоматически перейдет на следующую строку, поскольку в ней есть символ ` .

Однако, когда я нажимаю F5, это работает как шарм. Прошу простить меня за незнание PowerShell, но что я здесь делаю не так?

Дополнительная информация : это моя информация о PowerShell:

  • Имя: Windows PowerShell ISE Host
  • Версия: 5.1

2 ответа

Решение

Ваши ошибки происходят из-за функций PowerShell ISE.

Сначала вы пытаетесь использовать то, F8что называется «Выполнить выделение», в первой строке, но без выбора. Это неявно выберет все символы первой строки, а затем попытается запустить это.

Когда вы это сделаете, вы получите ошибку неполного строкового токена, потому что синтаксический анализатор обнаружил одиночный обратный апостроф `(escape-символ) без символа после него. Это потому, что новая строка в конце строки, которую обычно экранирует обратная кавычка (так она работает как символ продолжения строки), отсутствует, поскольку выделение одной строки не включало ее.

Во-вторых, когда я выделяю только первую строку, щелкая слева от номеров строк

Теперь в этом случае вы заметите, что ваш выбор поместил курсор в начало следующей строки. Это означает , что этот выбор делает включать символ новой строки, и поэтому теперь у вас есть полный струнный маркер.

Ваша ошибка в том, что теперь вы завершили свою команду запятой, как будто вы собираетесь передать больше параметров, а затем ничего не идет (остальные параметры не были включены в ваш выбор).


Корень проблемы в том, что команды в ISE, которые имеют дело с запуском выбора, делают именно это, поэтому, если вы хотите, чтобы они включали вещи, которые находятся в следующей строке, вы должны также включить их в выборку.


В качестве побочного примечания я мог бы порекомендовать вам поискать элементы кода, которые позволяют естественным образом использовать разрывы строк, например трубу | символы, операторы и фигурные скобки блока сценария {}.

      Get-WmiObject win32_service | 
    Where-Object { 
        $_.pathname -notlike "C:\windows\*" -and 
        $_.startmode -eq "auto" -and 
        $_.startname -eq "localsystem"
    } | 
    Select-Object displayname, pathname, startmode, startname | 
    Format-List | 
    Out-Host

Это не решает вашу проблему выбора, но, на мой взгляд, лучше читать и не требует неудобной обратной кавычки.

Следуя за комментарием ссылки @Santiagos:

Это называется прекращением действия заявления. При использовании Powershell есть 2 символа завершения оператора .

  1. Точка с запятой - ;
  2. Новая строка (иногда)

Правило для новой строки только иногда связано с характером того, как некоторые пользователи будут использовать команды. В основном это означает, что если предыдущий текст синтаксически является полным оператором, новая строка считается завершением оператора. Итак, если он не завершен, новая строка рассматривается как пробел.

Быстрый пример:

      PS C:\Users\Abraham> 3 +
>> 4
7

Когда я добавил + оператор, он ожидал другого аргумента, поэтому он не сработал.

В вашем случае я предполагаю, что ошибка возникла из PowerShells Tokenizer ( лексический анализатор) при синтаксическом анализе вашей команды, поскольку он считывает ваш обратный апостроф как escape-символ для вашей запятой (при условии, что он был завершен - отсюда терминатор оператора - чтение следующей строки как символ новой строки, а не пробел); на мой взгляд ( и кто-нибудь поправит меня, если я ошибаюсь), я думаю, что это была ошибка, которая была ложноположительной .

Backtik (`), также известный как escape-символ, может удлинить строку, которая не является расширяемой. Если последний символ в строке - обратная кавычка, то новая строка будет рассматриваться как пробел, а не « новая строка ».

Таким образом, вам не нужна обратная кавычка из-за вашей запятой ( ,) сообщая Powershell, что после него идет еще кое-что, что мы ссылаемся на второй абзац, поскольку он синтаксически неполный.

В итоге: это была ошибка в конце PowerShell (:

PS - Извините за длинный пост, так как первая часть на самом деле не нужна для ответа на ваш вопрос; просто некоторая информация, которая может помочь вам понять, как это происходит.

РЕДАКТИРОВАТЬ:

Не видел F8будучи виновником здесь lol, спасибо @briantist за указание на это. Ошибка не была на стороне Powershells. Не обращайте внимания на этот пост (:

Другие вопросы по тегам