Як ввести багаторядкову команду


425

Чи можна розділити командний рядок PowerShell на кілька рядків?

У Visual Basic я можу використовувати підкреслення ( _) для продовження команди в наступному рядку.


3
Питання "чому б не нахилити риски" добре висвітлено в PowerShell в дії Брюса Пайєта в дії ; чудова книга. Брюс має широкі знання історії мов програмування. З нетерпінням чекаю V2 цієї книги.
Джей Базузі


1
Вибачте, якщо офтопік, але якщо ви хочете подати скрипт з shкомандою, конфігурація bash дотримується, щоб ви могли використовувати зворотну косу рису. У цьому випадку ваш сценарій також повинен мати закінчення у стилі unix.
kon psych

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

Відповіді:


634

Ви можете використовувати пробіл з наступним гробовим акцентом (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

Я щойно з’ясував, що між задньою галочкою та розривом лінії не повинно бути жодного символу. Навіть пробіл призведе до того, що команда не працює.


10
Хоча це технічно не є відповіддю на питання, +1, оскільки це абсолютно важливо. Я тільки що це з’ясував важким шляхом і, безумовно, уникнути зворотного галочки в майбутньому розвитку, де це можливо.
Дейв Маркл

4
Таким чином, по суті немає надійного способу пробити довгу лінію в Powershell. Недарма я скрізь бачу ці сценарії з обох екранів на 2 екрани . #ShakeMyHead
RayLuo

Я теж боровся з цим ... Ви можете вставити вкладений коментар перед зворотним галочкою, щоб включити коментар, як-от так: Some-Command `-arg1 <# пояснити арг 1 #>` -arg2 <# пояснити арг 2 #>
joelsand

2
Урх. Це робить код PowerShell надмірно важким для розміщення в документації чи веб-сайтах, побоюючись, що команда буде прочитана неправильно людиною при використанні Shift + Enter, або буде неправильно проаналізована в командному рядку ISE при використанні зворотного галочки.
GuitarPicker

Вниз голосування через характер коментаря (що не є повною відповіддю на початкове запитання).
CodeBreaker

38

У більшості мов, подібних до С, я навмисно розміщую брекети там, де, думаю, вони роблять код найпростішим для читання.

Аналізатор PowerShell розпізнає, коли заява явно не завершена, і переглядає наступний рядок. Наприклад, уявіть командлет, який приймає необов'язковий параметр блоку сценарію:

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

якщо блок сценарію дуже довгий, ви можете написати:

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

Але це не спрацює: аналізатор побачить два твердження. Перший є, Get-Fooа другий - блок скриптів. Натомість я пишу:

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

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

Оскільки цей випадок вимагає, щоб відкрита дужка була у попередньому рядку, я дотримуюсь цього шаблона всюди:

    якщо (умова) {
        .....
    }

Зауважте, що ifзаяви вимагають блоку скриптів у граматиці мови, тому аналізатор буде шукати наступний рядок для блоку сценарію, але для послідовності я зберігаю відкриту дужку в тому ж рядку.

Просто, у випадку довгих трубопроводів, я перериваюсь після символу труби ( |):

    $ project.Items | 
        ? {$ _. Ключ -eq "ProjectFile"} |
        % {$ _. Значення} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }

як же ifі foreachта tryробота тоді? вони дозволяють блокувати сценарії в наступному рядку ... це означає, що це можливе
Нахт - Відновіть Моніку

@Nacht: З іржавої пам’яті: заяви, для яких потрібен блок скриптів, відповідно до граматики мови, будуть проходити аналіз нового рядка, щоб знайти його. Чи може хтось підтвердити?
Джей Базузі

2
@Nacht: "Але це не спрацює" малося на увазі ситуацію, коли подальші параметри необов'язкові, у більшості випадків.
Джей Базузі

1
ах я бачу, що ти маєш на увазі зараз. тож "якщо" та "foreach" насправді не є командлетами - вони є частиною граматики, тим самим змушуючи її виглядати минулим до наступного рядка. то чи не існує способу дозволити визначеній користувачем функції читати блок скриптів із наступного рядка? я вважаю, що ваша відповідь вище відповідає саме на це питання.
Нахт - Відновлення Моніки

29

Щоб розширити відповідь на cristobalito :

Я припускаю, що ви говорите про командний рядок - якщо він знаходиться в сценарії, то новий рядок> діє як роздільник команди.

У командному рядку використовуйте крапку з комою ';'

Наприклад:

Підпишіть скрипт PowerShell у командному рядку. Немає розривів рядків.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}

10
Не відповідь на запитання, але ваша відповідь відповіла на моє запитання. :)
Фредерік

1
Це цікаво, але це протилежне тому, що просили ОП. ОП хотів розділити одну команду на кілька рядків; ви пояснили, як об’єднати кілька команд в один рядок.
Даніель Янковський

17

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


2
Це чудова порада для редагування багаторядкових тут-рядків, які інакше жахливо редагувати, якщо ви не знаєте SHIFT-ENTERхитрості.
dpw

1
Я вважаю, що це стосується консольної версії PowerShell лише при використанні PSReadLineмодуля або його еквівалента. У стандартних вхідних системах консолі Windows функціонально Enterі Shift+Enterфункціонально еквівалентні.
Bill_Stewart

@Bill_Stewart вірно, він працює в консолі ISE без PSReadline, але не в хості консолі.
британіст

2
Для уточнення: 1) PSReadlineМодуль працює в консолі хоста тільки (НЕ ISE). 2) Shift+Enterпрацює в хості консолі лише при використанні PSReadline. 3) Shift+Enterзавжди працював в ISE. 4) Якщо хост консолі використовується без PSReadline, Shift+Enterфункціонально еквівалентний натисканню Enter.
Bill_Stewart

2
це правильна відповідь, та, яка прийнята і має 400 голосів, є дуже заплутаною і марною !!
ФЛІКЕР

4

Якщо ви намагаєтесь розділити рядки на кілька рядків, ви можете використовувати "+". Наприклад:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

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

$header = "Make,ComputerName,Model,Windows Version"

2

Я припускаю, що ви говорите про командний рядок - якщо він знаходиться в сценарії, то новий рядок виступає як роздільник команди.

У командному рядку використовуйте крапку з комою ';'


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

Просто додайте сюди кутовий корпус. Це може заощадити 5 хвилин. Якщо ви використовуєте ланцюжок дій, вам потрібно поставити "". в кінці рядка залиште пробіл, за яким слід "" "(backtick). Я виявив це важким шляхом.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.