Как ввести многострочную команду

427

Можно ли разбить командную строку PowerShell на несколько строк?

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

eXXL
источник
3
Вопрос «почему не происходит обратная косая черта» хорошо освещен в PowerShell Брюса Пайетта в действии ; отличная книга. Брюс обладает обширными знаниями истории языков программирования. С нетерпением жду V2 этой книги.
Джей Базузи
3
Дубликат ... stackoverflow.com/questions/2608144/…
SteveC
1
Извините, если оффтоп, но если вы хотите отправить скрипт с помощью shкоманды, соглашения bash сохраняются, поэтому вы можете использовать обратную косую черту. В этом случае ваш скрипт также должен иметь окончания в стиле Unix.
Кон Псих
просто используйте `символ для разделения команд на несколько строк
Асад

Ответы:

636

Вы можете использовать пробел с последующим серьезным акцентом (backtick):

Get-ChildItem -Recurse `
  -Filter *.jpg `
  | Select LastWriteTime

Однако это необходимо только в таких случаях, как показано выше. Обычно вы получаете автоматическое продолжение строки, когда команда не может быть синтаксически завершена в этой точке. Это включает запуск нового элемента конвейера:

Get-ChildItem |
  Select Name,Length

будет работать без проблем, так как после |команды не может быть завершена, так как отсутствует другой элемент конвейера. Также открывающиеся фигурные скобки или любые другие скобки позволят непосредственно продолжить строку:

$x=1..5
$x[
  0,3
] | % {
  "Number: $_"
}

Аналогично |запятой также будет работать в некоторых контекстах:

1,
2

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

return
  5

не будет работать.

Наконец, строки (во всех вариантах) также могут выходить за пределы одной строки:

'Foo
bar'

Они включают разрывы строк внутри строки, затем.

детеныш
источник
4
И не забудьте упомянуть, что некоторые другие токены также действуют как продолжатели строк, например, |и {.
Кит Хилл
1
@Keith: Спасибо, я включил это. Это было, вероятно, слишком очевидно, чтобы упоминать ;-)
Джои
16
Нет, хорошо, что эти другие символы задокументированы для дальнейшего использования.
Кит Хилл
1
@JackDouglas: Вы можете иметь разрыв строки сразу после открывающей скобки, но, очевидно, не внутри выражения перед оператором. При этом, я считаю, что это упущение в грамматике.
Джои
10
Продолжение строки не работает в командной панели ISE, по-видимому.
Хоури Джордано
64

Я только что узнал, что не должно быть никакого символа между обратным тиком и разрывом строки. Даже пробел заставит команду не работать.

Neffets
источник
10
Хотя это технически не ответ на вопрос, +1, потому что это абсолютно необходимо. Я только что понял это трудным путем, и, конечно, буду избегать галочки в будущем развитии, где это возможно.
Дэйв Маркл
4
Таким образом, в Powershell нет надежного способа разорвать длинную очередь. Неудивительно, что я склонен видеть эти сценарии PowerShell с двумя экранами где угодно . #ShakeMyHead
RayLuo
Я тоже боролся с этим ... вы можете вставить встроенный комментарий перед обратным тиканом, чтобы добавить комментарий, например: Some-Command `-arg1 <# объяснение arg 1 #>` -arg2 <# объяснение arg 2 #>
Joelsand
2
Urgh. Это делает код PowerShell излишне трудным для публикации в документации или на веб-сайтах, опасаясь, что команда будет либо неправильно прочитана человеком при использовании Shift + Enter, либо неправильно проанализирована в командной строке ISE при использовании обратного галочки.
GuitarPicker
Голосование вниз по причине характера комментария (который не является полным ответом на исходный вопрос).
CodeBreaker
38

В большинстве C-подобных языков я стараюсь размещать свои скобки там, где, как мне кажется, они делают код легким для чтения.

Синтаксический анализатор PowerShell распознает, когда утверждение явно не завершено, и переходит к следующей строке. Например, представьте командлет, который принимает необязательный параметр блока скрипта:

    Get-Foo {............}

если блок скрипта очень длинный, вы можете написать:

    Get-Foo
    {
        ...............
        ...............
        ...............
    }

Но это не сработает: парсер увидит два утверждения. Первый, Get-Fooа второй блок скриптов. Вместо этого я пишу:

    Get-Foo {
        ...............
        ...............
        ...............
    }

Я мог бы использовать символ продолжения строки (`), но это затрудняет чтение кода и вызывает ошибки.

Поскольку этот случай требует, чтобы открытая скобка была в предыдущей строке, я следую этому шаблону везде:

    if (условие) {
        .....
    }

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

Одновременно, в случае длинных конвейеров, я ломаю после символа трубы ( |):

    $ project.Items | 
        ? {$ _. Key -eq "ProjectFile"} |
        % {$ _. Value} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }
Джей Базузи
источник
как же ifи foreachи tryработа тогда? они разрешают блоки сценариев на следующей строке ... это означает, что это возможно
Nacht - Восстановить Монику
@Nacht: Из ржавой памяти: операторы, для которых требуется блок скрипта, в соответствии с грамматикой языка, проанализируют символ новой строки, чтобы найти его. Кто-нибудь может подтвердить?
Джей Базузи
2
@Nacht: «Но это не сработает» относится к ситуациям, когда дополнительные параметры являются необязательными, что в большинстве случаев.
Джей Базузи
1
Ах, я понимаю, что ты имеешь в виду сейчас. поэтому «if» и «foreach» на самом деле не являются командлетами - они фактически являются частью грамматики, что вынуждает ее смотреть в следующую строку. тогда нет ли способа позволить пользовательской функции читать блок скрипта из следующей строки? Я полагаю, что ваш ответ выше точно отвечает на этот вопрос.
Nacht - Восстановить Монику
29

Чтобы расширить ответ кристобалито :

Я предполагаю, что вы говорите о командной строке - если это в сценарии, то новая строка> действует как разделитель команд.

В командной строке используйте точку с запятой ';'

Например:

Подпишите сценарий PowerShell в командной строке. Без разрывов строк.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}
Alex
источник
10
Не ответ на вопрос, но ваш ответ ответил на мой вопрос. :)
Фредерик
1
Это интересно, но это противоположно тому, что спрашивал ОП. ОП хотел разделить одну команду на несколько строк; Вы объяснили, как объединить несколько команд в одну строку.
Даниэль Янковский
17

В PowerShell и PowerShell ISE также можно использовать Shift+ Enterв конце каждой строки для многострочного редактирования (вместо стандартного обратного удара `).

Плохой
источник
2
Это отличный совет для редактирования многострочных здесь-строк, которые иначе ужасно редактировать, если вы не знаете SHIFT-ENTERхитрости.
dpw
1
Я считаю, что это имеет место в консольной версии PowerShell только при использовании PSReadLineмодуля или его эквивалента. В стандартной консоли Windows функции ввода Enterи Shift+Enterфункционально эквивалентны.
Bill_Stewart
@Bill_Stewart true, он работает в консоли ISE без PSReadline, но не в консоли узла.
бриантист
2
Для уточнения: 1) PSReadlineМодуль работает в консоли хоста только (не ISE). 2) Shift+Enterработает в консоли хоста только при использовании PSReadline. 3) Shift+Enterвсегда работал в ИСЕ. 4) Если используется консольный хост без PSReadline, Shift+Enterфункционально эквивалентно нажатию Enter.
Bill_Stewart
2
это правильный ответ, тот, который принят и имеет 400 голосов, очень запутан и бесполезен !!
FLICKER
4

Если вы пытаетесь разделить строки на несколько строк, вы можете использовать «+». Например:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Будет выглядеть так:

$header = "Make,ComputerName,Model,Windows Version"
Стив Феллвок
источник
2

Я предполагаю, что вы говорите о командной строке - если это в сценарии, то новая строка действует как разделитель команд.

В командной строке используйте точку с запятой ';'

cristobalito
источник
1
  1. Используйте точку с запятой ;для разделения команды
  2. Замените двойную обратную косую черту \\на любую обратную косую черту \.
  3. Используйте "'для передачи безопасного адреса для переключения команды, например "PATH".

Эта команда ps1 устанавливает языковой сертификат pfx.

powershell -Command "$pfxPassword = ConvertTo-SecureString -String "12345678" -Force -AsPlainText ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\My -Password $pfxPassword ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\Root -Password $pfxPassword"
Мусульманин Шахсаван
источник
0

Существует так много способов продолжить строку в powershell, с помощью пробелов, скобок, скобок, операторов, точек, даже с запятой. Вот блог об этом: https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html

Вы можете продолжить сразу после таких утверждений, как foreach, и если так.

js2010
источник
0

Просто используйте символ `для разделения команд на многострочном

Асад Шакил
источник
0

Просто добавьте угловой случай здесь. Это может сэкономить вам 5 минут. Если вы используете цепочку действий, вам нужно поставить «.» в конце строки оставьте пробел, за которым следует «` »(обратный удар). Я нашел это трудным путем.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Цзян Хуан
источник