Jak wprowadzić polecenie wieloliniowe


425

Czy można podzielić wiersz poleceń programu PowerShell na wiele wierszy?

W Visual Basic mogę użyć znaku podkreślenia ( _), aby kontynuować polecenie w następnym wierszu.


3
Pytanie „dlaczego nie jest odwrotne” jest ładnie ujęte w PowerShell w działaniu Bruce'a Payette'a ; świetna książka. Bruce ma szeroką wiedzę na temat historii języków programowania. Czekam na drugą część tej książki.
Jay Bazuzi


1
Przepraszam, jeśli nie dotyczy, ale jeśli chcesz przesłać skrypt za pomocą shpolecenia, obowiązują konwencje bash, abyś mógł używać odwrotnego ukośnika. W takim przypadku skrypt powinien mieć również zakończenia w stylu uniksowym.
kon psych

wystarczy użyć znaku `, aby rozdzielić polecenia w wielu wierszach
Asad Shakeel,

Odpowiedzi:


634

Możesz użyć spacji, a następnie grobowego akcentu (kliknięcie w tył):

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

Jest to jednak konieczne tylko w takich przypadkach, jak pokazano powyżej. Zwykle uzyskuje się automatyczną kontynuację linii, gdy polecenie nie może być w tym momencie zakończone składniowo. Obejmuje to uruchomienie nowego elementu potoku:

Get-ChildItem |
  Select Name,Length

będzie działać bezproblemowo, ponieważ po wykonaniu |polecenia nie można ukończyć, ponieważ brakuje innego elementu potoku. Również otwieranie nawiasów klamrowych lub innego rodzaju nawiasów pozwoli bezpośrednio kontynuować linię:

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

Podobnie |jak przecinek, działa również w niektórych kontekstach:

1,
2

Należy pamiętać jednak, podobny do JavaScript za automatycznego wstawiania średnik , istnieje kilka rzeczy, które są podobnie łamane, ponieważ przerwa linia występuje w punkcie, gdzie to jest poprzedzone poprawnym stwierdzeniem:

return
  5

nie będzie działać.

Wreszcie ciągi (we wszystkich odmianach) mogą również rozciągać się poza jedną linię:

'Foo
bar'

Uwzględniają zatem podział wiersza w ciągu.


4
I nie zapomnij wspomnieć, że niektóre inne tokeny działać również jako kontynuatorzy linii przykład |i {.
Keith Hill

1
@Keith: Dzięki, załączyłem to. Były to chyba zbyt oczywiste, aby o nich wspominać ;-)
Joey

16
Nie, dobrze jest mieć te inne znaki udokumentowane do wykorzystania w przyszłości.
Keith Hill

1
@JackDouglas: Możesz mieć podział linii bezpośrednio po nawiasie otwierającym, ale najwyraźniej nie w obrębie wyrażenia przed operatorem. Biorąc to pod uwagę, uważam, że to przeoczenie gramatyki.
Joey,

10
Najwyraźniej kontynuacja linii nie działa w panelu poleceń ISE.
Khouri Giordano

64

Właśnie się dowiedziałem, że między tyknięciem wstecznym a łamaniem linii nie może być żadnego znaku. Nawet białe znaki spowodują, że polecenie nie będzie działać.


10
Chociaż technicznie nie jest to odpowiedź na pytanie, +1, ponieważ jest to absolutnie niezbędne. Właśnie to odkryłem na własnej skórze i na pewno będę unikać tykania wstecz w przyszłym rozwoju tam, gdzie to możliwe.
Dave Markle

4
W zasadzie nie ma solidnego sposobu na przełamanie długiej linii w PowerShell. Nic dziwnego, że wszędzie tam widzę te skrypty PowerShell na 2 ekrany . #ShakeMyHead
RayLuo

Walczyłem też z tym ... możesz wstawić komentarz wbudowany przed zaznaczeniem wstecz, aby dołączyć komentarz, taki jak ten: Some-Command `-arg1 <# wyjaśnij arg 1 #>` -arg2 <# wyjaśnij arg 2 #>
joelsand

2
Urgh. Powoduje to, że kod programu PowerShell jest niepotrzebnie trudny do opublikowania w dokumentacji lub witrynach internetowych, ponieważ obawia się, że polecenie zostanie źle odczytane przez człowieka przy użyciu Shift + Enter, lub niepoprawnie przeanalizowane w wierszu polecenia ISE podczas używania tylnego tiku.
GuitarPicker,

Głosuj w dół ze względu na charakter komentarza (który nie jest pełną odpowiedzią na pierwotne pytanie).
CodeBreaker

38

W większości języków podobnych do C zastanawiam się nad umieszczeniem nawiasów klamrowych w miejscu, które moim zdaniem ułatwi ich odczytanie.

Analizator składni programu PowerShell rozpoznaje, kiedy instrukcja wyraźnie nie jest kompletna, i przechodzi do następnego wiersza. Na przykład wyobraź sobie cmdlet, który pobiera opcjonalny parametr bloku skryptu:

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

jeśli blok skryptu jest bardzo długi, możesz napisać:

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

Ale to nie zadziała: parser zobaczy dwie instrukcje. Pierwszym jest, Get-Fooa drugim blokiem skryptu. Zamiast tego piszę:

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

Mógłbym użyć znaku kontynuacji linii (`), ale to sprawia, że ​​kod jest trudny do odczytania i powoduje błędy.

Ponieważ ten przypadek wymaga otwarcia nawiasu klamrowego w poprzedniej linii, wszędzie podążam za tym wzorem:

    if (warunek) {
        .....
    }

Zauważ, że ifinstrukcje wymagają bloku skryptu w gramatyce językowej, więc parser będzie szukał w następnym wierszu bloku skryptu, ale dla zachowania spójności trzymam otwarte nawiasy klamrowe w tej samej linii.

Po prostu, w przypadku długich rurociągów, łamię się po znaku potoku ( |):

    $ project.Items | 
        ? {$ _. Klucz -eq „ProjectFile”} |
        % {$ _. Wartość} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }

w jaki sposób ifi foreachi trypraca wtedy? pozwalają na blokowanie skryptów w następnym wierszu ... to znaczy, że to możliwe
Nacht - Przywróć Monikę

@Nacht: Z zardzewiałej pamięci: instrukcje, które wymagają bloku skryptu, zgodnie z gramatyką języka, zostaną przeanalizowane przez nowy wiersz, aby go znaleźć. Czy ktoś może potwierdzić?
Jay Bazuzi

2
@Nacht: „Ale to nie zadziała” odnosiło się do sytuacji, w których dalsze parametry są opcjonalne, co w większości przypadków.
Jay Bazuzi,

1
ah rozumiem, co masz na myśli teraz. więc „if” i „foreach” nie są tak naprawdę cmdletami - stanowią one wszystkie elementy gramatyki, zmuszając w ten sposób do przejścia do następnej linii. czy nie ma sposobu, aby funkcja zdefiniowana przez użytkownika odczytała blok skryptu z następnego wiersza? przypuszczam, że powyższa odpowiedź odpowiada dokładnie na to pytanie.
Nacht - Przywróć Monikę

29

Aby rozwinąć odpowiedź cristobalito :

Zakładam, że mówisz o wierszu polecenia - jeśli jest w skrypcie, to nowy wiersz> działa jak separator poleceń.

W wierszu polecenia użyj średnika „;”

Na przykład:

Podpisuj skrypt PowerShell w wierszu polecenia. Brak podziałów linii.

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

10
Nie odpowiedź na pytanie, ale twoja odpowiedź odpowiedziała na moje pytanie. :)
Frederik

1
To ciekawe, ale jest przeciwieństwem tego, o co prosiła OP. OP chciał podzielić jedno polecenie na kilka linii; wyjaśniłeś, jak połączyć kilka poleceń w jedną linię.
Daniel Yankowsky

17

W PowerShell i PowerShell ISE można również używać Shift+ Enterna końcu każdej linii do edycji wielowierszowej (zamiast standardowego backticka `).


2
To świetna wskazówka do edytowania wieloliniowych ciągów znaków, które w przeciwnym razie byłyby straszne do edycji, jeśli nie znasz SHIFT-ENTERsztuczki.
dpw

1
Wierzę, że tak jest w przypadku konsoli PowerShell tylko w przypadku korzystania z PSReadLinemodułu lub równoważnego. W standardowych funkcji wejściowych konsoli Windows Enteri Shift+Entersą funkcjonalnie równoważne.
Bill_Stewart

@Bill_Stewart true, działa w konsoli ISE bez PSReadline, ale nie w hoście konsoli.
briantist

2
Wyjaśnienie: 1) PSReadlineModuł działa tylko na hoście konsoli (nie na ISE). 2) Shift+Enterdziała na hoście konsoli tylko podczas używania PSReadline. 3) Shift+Enterzawsze pracował w ISE. 4) Jeśli używasz hosta konsoli bez PSReadline, Shift+Enterjest to funkcjonalnie równoważne z naciśnięciem Enter.
Bill_Stewart

2
to właściwa odpowiedź, ta, która została zaakceptowana i ma 400 głosów w górę, jest bardzo myląca i bezużyteczna !!
FLICKER

4

Jeśli próbujesz rozdzielić ciągi znaków na wiele wierszy, możesz użyć znaku „+”. Na przykład:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Będzie wyglądał tak:

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

2

Zakładam, że mówisz o wierszu polecenia - jeśli jest w skrypcie, to nowy wiersz działa jak separator poleceń.

W wierszu polecenia użyj średnika „;”


1
  1. Użyj średnika, ;aby oddzielić polecenie
  2. Zastąp podwójny ukośnik \\odwrotny \.
  3. Służy "'do przekazywania bezpiecznego adresu, aby przełączać polecenia takie jak „PATH”.

To polecenie ps1 zainstaluj lokalny certyfikat 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

Po prostu dodaj tutaj skrzynkę narożną. Może ci to zaoszczędzić 5 minut. Jeśli używasz łańcucha działań, musisz wpisać „.” na końcu wiersza pozostaw spację, po której następuje „(”). Przekonałem się o tym na własnej skórze.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.