Cách nhập lệnh nhiều dòng


425

Có thể tách một dòng lệnh PowerShell trên nhiều dòng không?

Trong Visual Basic tôi có thể sử dụng dấu gạch dưới ( _) để tiếp tục lệnh trong dòng tiếp theo.


3
Câu hỏi "tại sao không gạch chéo ngược" được trình bày độc đáo trong PowerShell in Action của Bruce Payette ; cuốn sách tuyệt vời. Bruce có kiến ​​thức rộng về lịch sử ngôn ngữ lập trình. Mong V2 của cuốn sách này.
Jay Bazuzi


1
Xin lỗi nếu offtopic nhưng nếu bạn muốn gửi tập lệnh bằng shlệnh, các quy ước bash giữ để bạn có thể sử dụng dấu gạch chéo ngược. Trong trường hợp đó, kịch bản của bạn cũng nên có kết thúc kiểu unix.
kon tâm lý

chỉ cần sử dụng `character để tách lệnh trên nhiều dòng
Asad Shakeel

Câu trả lời:


634

Bạn có thể sử dụng khoảng trắng theo dấu trọng âm (backtick):

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

Tuy nhiên, điều này chỉ cần thiết trong các trường hợp như được hiển thị ở trên. Thông thường, bạn nhận được tiếp tục dòng tự động khi một lệnh không thể hoàn thành về mặt cú pháp tại thời điểm đó. Điều này bao gồm bắt đầu một yếu tố đường ống mới:

Get-ChildItem |
  Select Name,Length

sẽ hoạt động mà không gặp vấn đề gì sau khi |lệnh không thể hoàn thành do thiếu phần tử đường ống khác. Ngoài ra, mở dấu ngoặc nhọn hoặc bất kỳ loại dấu ngoặc đơn nào khác sẽ cho phép tiếp tục dòng trực tiếp:

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

Tương tự như |dấu phẩy cũng sẽ hoạt động trong một số ngữ cảnh:

1,
2

Mặc dù vậy, hãy ghi nhớ, tương tự như Chèn Dấu chấm phẩy tự động của JavaScript , có một số điều bị hỏng tương tự vì ngắt dòng xảy ra tại điểm được đặt trước câu lệnh hợp lệ:

return
  5

sẽ không làm việc.

Cuối cùng, chuỗi (trong tất cả các giống) cũng có thể mở rộng ra ngoài một dòng:

'Foo
bar'

Chúng bao gồm các ngắt dòng trong chuỗi, sau đó.


4
Và đừng quên đề cập rằng một số mã thông báo khác cũng đóng vai trò là người tiếp tục dòng, vd |{.
Keith Hill

1
@Keith: Cảm ơn, tôi đã bao gồm nó. Những điều đó có lẽ quá rõ ràng để đề cập đến ;-)
Joey

16
Không, thật tốt khi có những ký tự khác được ghi lại để tham khảo trong tương lai.
Keith Hill

1
@JackDoumund: Rõ ràng, bạn có thể ngắt dòng trực tiếp sau dấu ngoặc đơn mở, nhưng không nằm trong biểu thức trước toán tử, rõ ràng. Điều đó đang được nói, tôi tin rằng đó là một sự giám sát trong ngữ pháp.
Joey

10
Tiếp tục dòng không hoạt động trong khung lệnh ISE, rõ ràng.
Khouri Giordano

64

Tôi chỉ phát hiện ra rằng không được có bất kỳ ký tự giữa dấu sau và dấu ngắt dòng. Ngay cả khoảng trắng sẽ khiến lệnh không hoạt động.


10
Mặc dù về mặt kỹ thuật không phải là câu trả lời cho câu hỏi, +1 vì điều này là hoàn toàn cần thiết. Tôi chỉ phát hiện ra điều này một cách khó khăn, và chắc chắn sẽ tránh được sự lạc hậu trong phát triển trong tương lai bất cứ khi nào có thể.
Dave Markle

4
Vì vậy, về cơ bản không có cách nào mạnh mẽ để phá vỡ một hàng dài trong Powershell. Không có gì ngạc nhiên khi tôi có xu hướng nhìn thấy các tập lệnh powershell rộng 2 màn hình ở mọi nơi. #ShakeMyHead
RayLuo

Tôi cũng đang vật lộn với điều này ... bạn có thể chèn một nhận xét nội tuyến trước dấu tích ngược để bao gồm một nhận xét, như thế này: Một số lệnh `-arg1 <# giải thích arg 1 #>` -arg2 <# giải thích arg 2 #>
tham gia

2
Urgh. Điều này làm cho mã PowerShell không cần thiết phải đăng trong tài liệu hoặc trang web, vì sợ rằng lệnh sẽ bị đọc sai bởi con người nếu sử dụng Shift + Enter hoặc phân tích sai trong dòng lệnh của ISE khi sử dụng dấu kiểm ngược.
GuitarPicker

Bỏ phiếu xuống do tính chất của bình luận (không phải là câu trả lời hoàn chỉnh cho câu hỏi ban đầu).
CodeBreaker

38

Trong hầu hết các ngôn ngữ giống như C, tôi cố tình đặt dấu ngoặc của mình vào nơi tôi nghĩ rằng chúng làm cho mã dễ đọc nhất.

Trình phân tích cú pháp của PowerShell nhận ra khi một câu lệnh rõ ràng chưa hoàn thành và tìm đến dòng tiếp theo. Ví dụ: hãy tưởng tượng một lệnh ghép ngắn có tham số khối tập lệnh tùy chọn:

    Nhận-Foo {............}

nếu khối kịch bản quá dài, bạn có thể muốn viết:

    Nhận-Foo
    {
        ...............
        ...............
        ...............
    }

Nhưng điều này sẽ không hoạt động: trình phân tích cú pháp sẽ thấy hai câu lệnh. Đầu tiên là Get-Foovà thứ hai là một khối kịch bản. Thay vào đó, tôi viết:

    Nhận-Foo {
        ...............
        ...............
        ...............
    }

Tôi có thể sử dụng ký tự tiếp tục dòng (`) nhưng điều đó làm cho mã khó đọc và mời các lỗi.

Bởi vì trường hợp này yêu cầu niềng răng mở ở dòng trước, tôi theo mô hình đó ở mọi nơi:

    nếu (điều kiện) {
        .....
    }

Lưu ý rằng các ifcâu lệnh yêu cầu một khối tập lệnh trong ngữ pháp ngôn ngữ, vì vậy trình phân tích cú pháp sẽ tìm dòng tiếp theo cho khối tập lệnh, nhưng để thống nhất, tôi giữ dấu ngoặc mở trên cùng một dòng.

Simlarly, trong trường hợp đường ống dài, tôi ngắt sau ký tự đường ống ( |):

    $ dự án. Các mặt hàng | 
        ? {$ _. Key -eq "ProjectFile"} |
        % {$ _. Giá trị} | 
        % {$ _. Đánh giá giá trị} |
        % {
            .........
        }

như thế nào ifforeachtrylàm việc sau đó? họ cho phép các khối kịch bản trên dòng tiếp theo ... điều này có nghĩa là nó có thể xảy ra
Nacht - Tái lập lại

@Nacht: Từ bộ nhớ gỉ: các câu lệnh yêu cầu khối kịch bản, theo ngữ pháp ngôn ngữ, sẽ phân tích cú pháp qua một dòng mới để tìm một dòng. Bất cứ ai có thể xác nhận?
Jay Bazuzi

2
@Nacht: "Nhưng điều này sẽ không hoạt động" đã đề cập đến các tình huống trong đó các tham số tiếp theo là tùy chọn, đó là hầu hết các trường hợp.
Jay Bazuzi

1
ah tôi hiểu ý của bạn lúc này vì vậy "nếu" và "foreach" không thực sự là các lệnh ghép ngắn - chúng là một phần thực tế của ngữ pháp, do đó buộc nó phải nhìn qua dòng tiếp theo. Có cách nào để cho phép một hàm do người dùng xác định đọc một khối tập lệnh từ dòng tiếp theo không? tôi cho rằng câu trả lời trên của bạn trả lời chính xác câu hỏi đó.
Nacht - Phục hồi Monica

29

Để mở rộng câu trả lời của cristobalito :

Tôi giả sử bạn đang nói về dòng lệnh - nếu đó là trong một tập lệnh, thì một dòng mới> hoạt động như một dấu phân cách lệnh.

Trên dòng lệnh, sử dụng dấu chấm phẩy ';'

Ví dụ:

Ký một tập lệnh PowerShell trên dòng lệnh. Không ngắt dòng.

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

10
Không phải câu trả lời cho câu hỏi, nhưng câu trả lời của bạn đã trả lời câu hỏi của tôi. :)
Frederik

1
Điều đó thật thú vị, nhưng nó trái ngược với những gì OP đang hỏi. OP muốn chia một lệnh duy nhất qua nhiều dòng; bạn đã giải thích cách kết hợp một số lệnh trên một dòng.
Daniel Yankowsky

17

Trong PowerShell và PowerShell ISE, cũng có thể sử dụng Shift+ Enterở cuối mỗi dòng để chỉnh sửa đa dòng (thay vì backtick tiêu chuẩn `).


2
Đây là một mẹo hay để chỉnh sửa nhiều dòng ở đây - các chuỗi rất tệ khi chỉnh sửa nếu bạn không biết SHIFT-ENTERmẹo.
dpw

1
Tôi tin rằng đây chỉ là trường hợp trong phiên bản console của PowerShell khi sử dụng PSReadLinemô-đun hoặc tương đương. Trong các chức năng đầu vào của bàn điều khiển Windows tiêu chuẩn EnterShift+Entertương đương về chức năng.
Bill_Stewart

@Bill_Stewart đúng, nó hoạt động trong bảng điều khiển ISE không có PSReadline, nhưng không có trong Host Host.
sáng lập

2
Để làm rõ: 1) Các PSReadlinemô-đun làm việc trong các máy chủ giao diện điều khiển duy nhất (không ISE). 2) Shift+Enterlàm việc trong các máy chủ giao diện điều khiển duy nhất khi sử dụng PSReadline. 3) Shift+Enterđã luôn làm việc trong ISE. 4) Nếu sử dụng các máy chủ giao diện điều khiển mà không PSReadline, Shift+Entercó chức năng tương đương với nhấn Enter.
Bill_Stewart

2
Đây là câu trả lời đúng, câu trả lời được chấp nhận và có 400 phiếu bầu lên rất khó hiểu và vô dụng !!
FLICKER

4

Nếu bạn đang cố tách các chuỗi thành nhiều dòng, bạn có thể sử dụng "+". Ví dụ:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Sẽ trông giống như:

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

2

Tôi giả sử bạn đang nói về dòng lệnh - nếu đó là trong một tập lệnh, thì một dòng mới hoạt động như một dấu phân cách lệnh.

Trên dòng lệnh, sử dụng dấu chấm phẩy ';'


1
  1. Sử dụng dấu chấm phẩy ;để tách lệnh
  2. Thay thế dấu gạch chéo kép \\trên bất kỳ dấu gạch chéo ngược nào \.
  3. Sử dụng "'để chuyển địa chỉ an toàn để chuyển lệnh như "'PATH'".

Lệnh ps1 này cài đặt chứng chỉ pfx miền địa phương.

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

Chỉ cần thêm một trường hợp góc ở đây. Nó có thể giúp bạn tiết kiệm 5 phút. Nếu bạn sử dụng một chuỗi các hành động, bạn cần đặt "." ở cuối dòng, để lại một khoảng trắng theo sau là "` "(backtick). Tôi tìm thấy điều này một cách khó khăn.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.