Cara memasukkan perintah multi-line

426

Apakah mungkin membagi baris perintah PowerShell ke beberapa baris?

Dalam Visual Basic saya dapat menggunakan garis bawah ( _) untuk melanjutkan perintah di baris berikutnya.

eXXL
sumber
3
Pertanyaan "mengapa tidak backslash" tercakup dengan baik dalam PowerShell in Action karya Bruce Payette ; buku yang bagus. Bruce memiliki pengetahuan luas tentang sejarah bahasa pemrograman. Menantikan V2 buku ini.
Jay Bazuzi
1
Maaf jika offtopic tetapi jika Anda ingin mengirimkan skrip dengan shperintah, bash conventions tahan sehingga Anda dapat menggunakan backslash. Dalam hal ini skrip Anda juga harus memiliki akhiran gaya unix.
kon psych
cukup gunakan `karakter untuk memisahkan perintah pada banyak baris
Asad Shakeel

Jawaban:

635

Anda dapat menggunakan spasi diikuti oleh aksen kubur (backtick):

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

Namun, ini hanya diperlukan dalam kasus seperti yang ditunjukkan di atas. Biasanya Anda mendapatkan kelanjutan garis otomatis ketika sebuah perintah tidak dapat secara sintaksis selesai pada saat itu. Ini termasuk memulai elemen pipa baru:

Get-ChildItem |
  Select Name,Length

akan bekerja tanpa masalah karena setelah |perintah tidak dapat diselesaikan karena tidak ada elemen pipeline yang lain. Juga membuka kurung kurawal atau jenis kurung lainnya akan memungkinkan kelanjutan garis secara langsung:

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

Mirip dengan |koma juga akan berfungsi dalam beberapa konteks:

1,
2

Perlu diingat, meskipun, mirip dengan JavaScript ini otomatis Titik koma Penyisipan , ada beberapa hal yang sama rusak karena garis istirahat terjadi pada titik di mana ia adalah didahului oleh pernyataan valid:

return
  5

tidak akan bekerja.

Akhirnya, string (dalam semua varietas) juga dapat melampaui satu baris:

'Foo
bar'

Mereka termasuk jeda baris dalam string, lalu.

Joey
sumber
4
Dan jangan lupa untuk menyebutkan bahwa beberapa token lain juga bertindak sebagai penerus garis misalnya |dan {.
Keith Hill
1
@Keith: Terima kasih, saya memasukkannya. Itu mungkin terlalu jelas untuk disebutkan ;-)
Joey
16
Nah, ada baiknya memiliki karakter lain ini didokumentasikan untuk referensi di masa mendatang.
Keith Hill
1
@JackDouglas: Anda dapat memiliki jeda baris langsung setelah tanda kurung buka, tetapi tidak di dalam ekspresi sebelum operator, tampaknya. Yang sedang berkata, saya percaya bahwa menjadi kekeliruan dalam tata bahasa.
Joey
10
Kelanjutan garis tidak berfungsi di panel perintah ISE, tampaknya.
Khouri Giordano
64

Saya baru tahu bahwa tidak boleh ada karakter apa pun antara centang belakang dan pemecah baris. Bahkan spasi putih akan menyebabkan perintah tidak berfungsi.

Neffets
sumber
10
Meskipun ini secara teknis bukan jawaban untuk pertanyaan, +1 karena ini sangat penting. Saya baru saja menemukan ini dengan cara yang sulit, dan pasti akan menghindari tanda centang dalam pengembangan di masa depan sedapat mungkin.
Dave Markle
4
Jadi pada dasarnya tidak ada cara yang kuat untuk memutus garis panjang di Powershell. Tidak heran saya cenderung melihat skrip powershell 2-layar selebar itu di mana-mana. #ShakeMyHead
RayLuo
Saya juga kesulitan dengan ini ... Anda dapat memasukkan komentar sebaris sebelum tanda centang-kembali untuk memasukkan komentar, seperti ini: Some-Command `-arg1 <# jelaskan arg 1 #>` -arg2 <# jelaskan arg 2 #>
joelsand
2
Urgh. Ini membuat kode PowerShell tidak perlu sulit untuk diposkan dalam dokumentasi atau situs web, karena takut bahwa perintah tersebut akan salah dibaca oleh manusia jika menggunakan Shift + Enter, atau salah parsing di baris perintah ISE saat menggunakan centang kembali.
GuitarPicker
Suara turun karena sifat komentar (yang bukan jawaban lengkap untuk pertanyaan asli).
CodeBreaker
38

Dalam kebanyakan bahasa mirip C, saya sengaja menempatkan kurung kurawal di tempat yang menurut saya membuat kodenya lebih mudah dibaca.

Pengurai PowerShell mengenali kapan pernyataan jelas tidak lengkap, dan mencari ke baris berikutnya. Misalnya, bayangkan cmdlet yang mengambil parameter blok skrip opsional:

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

jika blok skrip sangat panjang, Anda mungkin ingin menulis:

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

Tapi ini tidak akan berhasil: parser akan melihat dua pernyataan. Yang pertama Get-Foodan yang kedua adalah blok skrip. Sebaliknya, saya menulis:

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

Saya bisa menggunakan karakter garis-kelanjutan (`) tetapi itu membuat kode sulit dibaca, dan mengundang bug.

Karena case ini mensyaratkan brace terbuka berada di baris sebelumnya, saya mengikuti pola itu di mana-mana:

    if (kondisi) {
        .....
    }

Perhatikan bahwa ifpernyataan memerlukan blok skrip dalam tata bahasa, sehingga parser akan mencari di baris berikutnya untuk blok skrip, tetapi untuk konsistensi, saya menjaga brace terbuka di baris yang sama.

Demikian pula, dalam kasus pipa panjang, saya mematahkan karakter pipa ( |):

    $ project.Items | 
        ? {$ _. Key -eq "ProjectFile"} |
        % {$ _. Nilai} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }
Jay Bazuzi
sumber
lalu bagaimana ifdan foreachdan trybekerja? mereka mengizinkan blok skrip pada baris berikutnya ... ini berarti mungkin
Nacht - Reinstate Monica
@ Kapal: Dari memori berkarat: pernyataan yang membutuhkan blok skrip, sesuai tata bahasa, akan diuraikan melewati baris baru untuk menemukan satu. Adakah yang bisa mengkonfirmasi?
Jay Bazuzi
2
@ Kapal: "Tapi ini tidak akan berhasil" mengacu pada situasi di mana parameter lebih lanjut adalah opsional, yang kebanyakan kasus.
Jay Bazuzi
1
ah saya mengerti maksud Anda sekarang. jadi "jika" dan "foreach" sebenarnya bukan cmdlet - mereka sebenarnya adalah bagian dari tata bahasa, sehingga memaksanya untuk melihat ke masa lalu ke baris berikutnya. Apakah tidak ada cara untuk membiarkan fungsi yang ditentukan pengguna membaca blok skrip dari baris berikutnya? Saya kira jawaban Anda di atas menjawab pertanyaan itu dengan tepat.
Nacht - Pasang kembali Monica
29

Untuk memperluas jawaban cristobalito :

Saya berasumsi Anda sedang berbicara tentang command-line - jika ada dalam skrip, maka baris-baru> bertindak sebagai pembatas perintah.

Di baris perintah, gunakan semi-colon ';'

Sebagai contoh:

Tanda tangani skrip PowerShell di baris perintah. Tidak ada jeda baris.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}
Alex
sumber
10
Bukan jawaban untuk pertanyaan itu, tetapi jawaban Anda menjawab pertanyaan saya. :)
Frederik
1
Itu menarik, tapi kebalikan dari apa yang ditanyakan OP. OP ingin membagi satu perintah di beberapa baris; Anda menjelaskan cara menggabungkan beberapa perintah ke satu baris.
Daniel Yankowsky
17

Di PowerShell dan PowerShell ISE, dimungkinkan juga untuk menggunakan Shift+ Enterdi akhir setiap baris untuk pengeditan multiline (bukan backtick standar `).

Buruk
sumber
2
Ini adalah tip yang bagus untuk mengedit multi-line di sini-string, yang sebaliknya mengerikan untuk diedit jika Anda tidak tahu SHIFT-ENTERtriknya.
dpw
1
Saya percaya ini adalah kasus di PowerShell versi konsol hanya ketika menggunakan PSReadLinemodul atau yang setara. Dalam fungsi input konsol Windows standar, Enterdan Shift+Entersecara fungsional setara.
Bill_Stewart
@ Bill_Stewart benar, ia bekerja di konsol ISE tanpa PSReadline, tetapi tidak di Host Console.
briantis
2
Untuk memperjelas: 1) PSReadlinemodul bekerja di konsol tuan rumah hanya (tidak ISE). 2) Shift+Enterbekerja di host konsol hanya ketika menggunakan PSReadline. 3) Shift+Enterselalu bekerja di ISE. 4) Jika menggunakan host konsol tanpa PSReadline, Shift+Entersecara fungsional setara dengan menekan Enter.
Bill_Stewart
2
ini adalah jawaban yang tepat, jawaban yang diterima dan mendapat 400 suara sangat membingungkan dan tidak berguna !!
FLICKER
4

Jika Anda mencoba memisahkan string menjadi beberapa baris, Anda dapat menggunakan "+". Sebagai contoh:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Akan terlihat seperti:

$header = "Make,ComputerName,Model,Windows Version"
Steve Fellwock
sumber
2

Saya berasumsi Anda sedang berbicara tentang command-line - jika ada dalam skrip, maka baris baru bertindak sebagai pembatas perintah.

Di baris perintah, gunakan semi-colon ';'

cristobalito
sumber
1
  1. Gunakan titik koma ;untuk memisahkan perintah
  2. Ganti backslash ganda \\pada backslash apa pun \.
  3. Gunakan "'untuk menyampaikan alamat aman untuk berganti perintah seperti "'PATH'".

Perintah ps1 ini menginstal sertifikat pfx lokal.

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"
Muslim Shahsavan
sumber
0
$scriptBlock = [Scriptblock]::Create(@'
  echo 'before'
  ipconfig /all
  echo 'after'
'@)

Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

sumber
tidak menggunakan backquote

Mike
sumber
0

Cukup gunakan karakter `untuk memisahkan perintah pada multiline

Asad Shakeel
sumber
0

Tambahkan saja kotak sudut di sini. Mungkin menghemat 5 menit. Jika Anda menggunakan serangkaian tindakan, Anda harus meletakkan "." di akhir baris, beri spasi diikuti dengan "` "(backtick). Saya menemukan ini dengan cara yang sulit.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Jian Huang
sumber