วิธีการป้อนคำสั่งหลายบรรทัด


425

เป็นไปได้หรือไม่ที่จะแบ่งบรรทัดคำสั่ง PowerShell เป็นหลาย ๆ บรรทัด?

ใน Visual Basic ฉันสามารถใช้ขีดล่าง ( _) เพื่อดำเนินการต่อคำสั่งในบรรทัดถัดไป


3
คำถามที่ว่า "ทำไมไม่แบ็กสแลช" ครอบคลุมอยู่ในPowerShell in Actionของ Bruce Payette ; หนังสือที่ดี บรูซมีความรู้กว้างเกี่ยวกับประวัติของภาษาโปรแกรม รอคอยที่จะ V2 ของหนังสือเล่มนี้
Jay Bazuzi


1
ขออภัยถ้าออฟไลน์ แต่ถ้าคุณจะส่งสคริปต์พร้อมshคำสั่งการประชุมทุบตีจะหยุดไว้เพื่อให้คุณสามารถใช้แบ็กสแลชได้ ในกรณีนี้สคริปต์ของคุณควรมีลักษณะสิ้นสุดยูนิกซ์
kon Psych

เพียงใช้อักขระ `เพื่อแยกคำสั่งในหลายบรรทัด
Asad Shakeel

คำตอบ:


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
และไม่ลืมที่จะพูดถึงว่าบางราชสกุลอื่น ๆ ยังทำหน้าที่เป็น continuators บรรทัดเช่นและ| {
Keith Hill

1
@ Keith: ขอบคุณฉันรวมไว้ อาจชัดเจนเกินไปที่จะพูดถึง ;-)
Joey

16
ไม่ดีที่มีตัวอักษรอื่น ๆ เหล่านี้ไว้ใช้อ้างอิงในอนาคต
Keith Hill

1
@JackDouglas: คุณสามารถมีตัวแบ่งบรรทัดได้โดยตรงหลังวงเล็บเปิด แต่ไม่ใช่ภายในนิพจน์ก่อนตัวดำเนินการ ที่ถูกกล่าวว่าฉันเชื่อว่าการกำกับดูแลในไวยากรณ์
Joey

10
ความต่อเนื่องของเส้นไม่สามารถใช้งานได้ในบานหน้าต่างคำสั่ง ISE
Khouri Giordano

64

ฉันเพิ่งพบว่าจะต้องไม่มีตัวละครใด ๆระหว่างเครื่องหมายขีดด้านหลังและตัวแบ่งบรรทัด แม้ช่องว่างจะทำให้คำสั่งไม่ทำงาน


10
แม้ว่าเทคนิคนี้ไม่ใช่คำตอบสำหรับคำถาม แต่ +1 เพราะสิ่งนี้สำคัญมาก ฉันเพิ่งพบสิ่งนี้ด้วยวิธีที่ยากลำบากและจะหลีกเลี่ยงการย้อนกลับในการพัฒนาในอนาคตหากเป็นไปได้
Dave Markle

4
ดังนั้นจึงไม่มีวิธีที่แข็งแกร่งในการทำลายเส้นยาวใน Powershell ไม่น่าแปลกใจที่ฉันมักจะเห็นสคริปต์ PowerShell ทั้งสองหน้าจอทุกที่ #ShakeMyHead
RayLuo

ฉันกำลังดิ้นรนกับเรื่องนี้เช่นกัน ... คุณสามารถแทรกความคิดเห็นแบบอินไลน์ก่อนติ๊กด้านหลังเพื่อรวมความคิดเห็นเช่นนี้: คำสั่งบางคำสั่ง -arg1 <# อธิบาย arg 1 #> `-arg2 2 # # อธิบาย arg 2 #>
joelsand

2
Urgh สิ่งนี้ทำให้รหัส PowerShell ยากที่จะโพสต์ในเอกสารหรือเว็บไซต์โดยไม่จำเป็นเนื่องจากกลัวว่าคำสั่งจะถูกอ่านโดยมนุษย์หากใช้ Shift + Enter หรือแยกวิเคราะห์ผิดในบรรทัดคำสั่งของ ISE เมื่อใช้เครื่องหมายขีดหลัง
GuitarPicker

ลงคะแนนเนื่องจากลักษณะของความคิดเห็น (ซึ่งไม่ใช่คำตอบที่สมบูรณ์สำหรับคำถามต้นฉบับ)
CodeBreaker

38

ในภาษาที่เหมือน C ส่วนใหญ่ฉันพิจารณาเกี่ยวกับการจัดฟันของฉันโดยที่ฉันคิดว่าพวกเขาทำให้โค้ดอ่านง่ายที่สุด

โปรแกรมแยกวิเคราะห์ของ PowerShell จดจำเมื่อคำสั่งไม่ชัดเจนและมองไปที่บรรทัดถัดไป ตัวอย่างเช่นลองนึกภาพ cmdlet ที่รับพารามิเตอร์บล็อกสคริปต์เผื่อเลือก:

    รับ -Foo {............ }

หากบล็อกสคริปต์ยาวมากคุณอาจต้องการเขียน:

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

แต่สิ่งนี้จะไม่ทำงาน: โปรแกรมแยกวิเคราะห์จะเห็นสองข้อความ สิ่งแรกคือGet-Fooและสิ่งที่สองคือบล็อกสคริปต์ ฉันเขียนแทน:

    รับ -Foo {
        ...............
        ...............
        ...............
    }

ฉันสามารถใช้ตัวอักษรต่อเนื่องบรรทัด (`) แต่ที่ทำให้รหัสที่ยากต่อการอ่านและเชิญแมลง

เนื่องจากกรณีนี้ต้องใช้วงเล็บปีกกาเปิดเพื่ออยู่ในบรรทัดก่อนหน้าฉันจึงทำตามรูปแบบนั้นทุกที่:

    ถ้า (เงื่อนไข) {
        .....
    }

โปรดทราบว่าifข้อความสั่งต้องใช้สคริปต์บล็อกในไวยากรณ์ภาษาดังนั้น parser จะค้นหาบรรทัดถัดไปสำหรับบล็อกสคริปต์ แต่เพื่อความมั่นคงฉันจะเปิดวงเล็บปีกกาในบรรทัดเดียวกัน

อย่างในกรณีของท่อยาว ๆ ฉันจะแยกตามตัวอักษรไพพ์ ( |):

    $ project.Items | 
        ? {$ _. Key -eq "ProjectFile"} |
        % {$ _. มูลค่า} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }

วิธีการที่ไม่ifและforeachและtryการทำงานแล้ว? พวกเขาช่วยให้บล็อกสคริปต์ในบรรทัดถัดไป ... ที่นี้หมายถึงว่ามันจะเป็นไปได้ MUT
Nacht - คืนสิทธิ์ให้กับโมนิก้า

@Nacht: จากหน่วยความจำที่มีสนิม: คำสั่งที่ต้องการบล็อกสคริปต์ตามไวยากรณ์ภาษาจะแยกบรรทัดใหม่เพื่อหาหนึ่งบรรทัด มีใครยืนยันได้บ้าง
Jay Bazuzi

2
@Nacht: "แต่นี่ใช้ไม่ได้" หมายถึงสถานการณ์ที่พารามิเตอร์เพิ่มเติมเป็นตัวเลือกซึ่งส่วนใหญ่แล้ว
Jay Bazuzi

1
อ่าฉันเห็นสิ่งที่คุณหมายถึงตอนนี้ ดังนั้น "if" และ "foreach" ไม่ใช่ cmdlets จริง ๆ - มันเป็นส่วนหนึ่งของไวยากรณ์ดังนั้นจึงบังคับให้มองผ่านบรรทัดถัดไป จะไม่มีวิธีให้ผู้ใช้กำหนดฟังก์ชันอ่านบล็อกสคริปต์จากบรรทัดถัดไปหรือไม่ ฉันคิดว่าคำตอบของคุณตอบคำถามข้างต้นว่า
Nacht - Reinstate Monica

29

หากต้องการขยายคำตอบของ cristobalito :

ฉันคิดว่าคุณกำลังพูดถึงในบรรทัดคำสั่ง - หากอยู่ในสคริปต์แล้วบรรทัดใหม่> ทำหน้าที่เป็นตัวคั่นคำสั่ง

บนบรรทัดคำสั่งให้ใช้เซมิโคลอน ';'

ตัวอย่างเช่น:

เซ็นชื่อสคริปต์ PowerShell บนบรรทัดคำสั่ง ไม่มีตัวแบ่งบรรทัด

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

10
ไม่ใช่คำตอบของคำถาม แต่คำตอบของคุณตอบคำถามของฉัน :)
Frederik

1
มันน่าสนใจ แต่มันตรงกันข้ามกับสิ่งที่ OP ถาม OP ต้องการแยกคำสั่งเดียวข้ามหลายบรรทัด คุณอธิบายวิธีรวมหลายคำสั่งไว้ในบรรทัดเดียว
Daniel Yankowsky

17

ใน PowerShell และ PowerShell ISE ก็เป็นไปได้ที่จะใช้Shift+ Enterในตอนท้ายของแต่ละบรรทัดสำหรับการแก้ไขแบบหลายบรรทัด (แทนที่จะเป็น backtick มาตรฐาน`)


2
นี่เป็นเคล็ดลับที่ยอดเยี่ยมสำหรับการแก้ไขสตริงหลายบรรทัดในที่นี้ซึ่งไม่ดีนักหากคุณไม่รู้SHIFT-ENTERเคล็ดลับ
dpw

1
ฉันเชื่อว่านี่เป็นกรณีใน PowerShell รุ่นคอนโซลเฉพาะเมื่อใช้PSReadLineโมดูลหรือเทียบเท่า ในฟังก์ชั่นอินพุตคอนโซลมาตรฐานของ Windows EnterและShift+Enterสามารถใช้งานได้เทียบเท่า
Bill_Stewart

@Bill_Stewart จริงมันทำงานในคอนโซล ISE โดยไม่ต้อง PSReadline แต่ไม่ได้อยู่ใน Console Host
ต้มตุ๋น

2
เพื่อชี้แจง: 1) PSReadlineโมดูลทำงานในคอนโซลโฮสต์เท่านั้น (ไม่ใช่ ISE) 2) Shift+Enterการทำงานในโฮสต์คอนโซลเท่านั้นPSReadlineเมื่อใช้ 3) Shift+Enterทำงานใน ISE เสมอ 4) ถ้าใช้โฮสต์คอนโซลโดยไม่PSReadline, เป็นหน้าที่เทียบเท่ากับการกดShift+Enter Enter
Bill_Stewart

2
นี่คือคำตอบที่ถูกต้องคำตอบที่ยอมรับและมี 400 คะแนนขึ้นไปนั้นทำให้สับสนและไร้ประโยชน์ !!
FLICKER

4

หากคุณพยายามแยกสตริงออกเป็นหลาย ๆ บรรทัดคุณสามารถใช้ "+" ตัวอย่างเช่น:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

จะมีลักษณะเช่น:

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

2

ฉันคิดว่าคุณกำลังพูดถึงในบรรทัดคำสั่ง - หากอยู่ในสคริปต์แล้วบรรทัดใหม่ทำหน้าที่เป็นตัวคั่นคำสั่ง

บนบรรทัดคำสั่งให้ใช้เซมิโคลอน ';'


1
  1. ใช้เซมิโคลอน;เพื่อแยกคำสั่ง
  2. แทนที่ทับขวาสองครั้งในเครื่องหมายใด\\\
  3. ใช้"'สำหรับส่งที่อยู่ที่ปลอดภัยเพื่อเปลี่ยนคำสั่งเช่น "'PATH'"

คำสั่ง ps1 นี้ติดตั้งใบรับรอง locale 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 และถ้าเช่นกัน




0

เพียงเพิ่มกรณีมุมที่นี่ อาจช่วยให้คุณประหยัด 5 นาที หากคุณใช้สายปฏิบัติการคุณต้องใส่ "." ที่ส่วนท้ายของบรรทัดเว้นช่องว่างตามด้วย "` "(backtick) ฉันพบสิ่งนี้ด้วยวิธีที่ยากลำบาก

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.