Cách phân chia các lệnh dài trên nhiều dòng trong PowerShell


227

Làm thế nào để bạn thực hiện một lệnh như sau trong PowerShell và chia nó thành nhiều dòng?

&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" -dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"


Câu trả lời:


322

Trailing backtick nhân vật, tức là,

&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
-verb:sync `
-source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" `
-dest:contentPath="c:\websites\xxx\wwwroot,computerName=192.168.1.1,username=administrator,password=xxx"

Vấn đề không gian trắng. Các định dạng cần thiết là Space`Enter.


1
Điều này dường như phá vỡ chức năng lịch sử lệnh (mũi tên lên); vì mỗi dòng hiển thị dưới dạng một lệnh riêng biệt. Có cách nào để giái quyết vấn đề này không?
Richard Ev

2
Nếu bạn đang chạy powershell 3 trở lên, hãy xem github.com/lzybkr/psreadline - truyền tải lịch sử được cố định cho các câu lệnh đa dòng.
x0n

43
Không gian phía trước dấu tích được yêu cầu # learn-the-hard-way
Josh Graham

29
@ josh-graham Và KHÔNG nên có bất kỳ khoảng trắng (hoặc bình luận nội tuyến nào) SAU khi đánh dấu lại. # học-the-khó chiều
RayLuo

1
Backticks dễ vỡ (như trạng thái bình luận ở trên) và khó tìm thấy khi phân tích hoặc xem xét một tệp. Câu trả lời của @StevenPenny sẽ tốt hơn nếu bạn muốn gỡ lỗi mã dễ dàng hơn.
mjd2

67

Một phương pháp khác để truyền đối số sạch hơn sẽ là splatter .

Xác định các tham số và giá trị của bạn dưới dạng hashtable như thế này:

$params = @{ 'class' = 'Win32_BIOS';
             'computername'='SERVER-R2';
             'filter'='drivetype=3';
             'credential'='Administrator' }

Và sau đó gọi lệnh của bạn như thế này:

Get-WmiObject @params

Microsoft Docs: Giới thiệu về Splatted

Tạp chí TechNet 2011: Windows PowerShell: Spleting

Có vẻ như nó hoạt động với Powershell 2.0 trở lên


5
Đây là điều tuyệt vời! VÀ bạn có thể thêm các thông số như thế này: $params.add('name','Bob Newhart') ramblingcookiemonster.wordpress.com/2014/12/01/...
bgmCoder

1
Dấu chấm phẩy là ok nhưng không cần thiết. Chỉ yêu cầu nếu có nhiều giá trị trên mỗi dòng.
jim bạch dương

38

À, và nếu bạn có một chuỗi rất dài mà bạn muốn chia tay, hãy nói về HTML, bạn có thể làm điều đó bằng cách đặt một @bên ở mỗi bên của bên ngoài "- như thế này:

$mystring = @"
Bob
went
to town
to buy
a fat
pig.
"@

Bạn nhận được chính xác điều này:

Bob
went
to town
to buy
a fat
pig.

Và nếu bạn đang sử dụng Notepad ++ , nó thậm chí sẽ làm nổi bật chính xác dưới dạng một chuỗi chuỗi.

Bây giờ, nếu bạn muốn chuỗi đó cũng chứa dấu ngoặc kép, chỉ cần thêm chúng vào, như thế này:

$myvar = "Site"
$mystring = @"
<a href="http://somewhere.com/somelocation">
Bob's $myvar
</a>
"@

Bạn sẽ nhận được chính xác điều này:

<a href="http://somewhere.com/somelocation">
Bob's Site
</a>

Tuy nhiên, nếu bạn sử dụng dấu ngoặc kép trong chuỗi @ như thế, Notepad ++ sẽ không nhận ra điều đó và sẽ tắt màu cú pháp như thể nó không được trích dẫn hoặc trích dẫn, tùy theo trường hợp.

Và điều tốt hơn là đây: bất cứ nơi nào bạn chèn một biến $, nó sẽ được giải thích! (Nếu bạn cần ký hiệu đô la trong văn bản, bạn thoát nó bằng dấu tick như thế này: `` $ not-a-biến`.)

ĐỂ Ý! Nếu bạn không đặt trận chung kết "@đầu dòng , nó sẽ thất bại. Tôi đã mất một giờ để nhận ra rằng tôi không thể nhận ra rằng trong mã của mình!

Đây là MSDN về chủ đề: Sử dụng Windows PowerShell ở đây


1
Thủ thuật gọn gàng, mặc dù nếu tôi có một biến $ ... nó dường như không hoạt động. Tôi nhận được "nhân vật không được phép sau tiêu đề chuỗi ở đây ..."
tofutim

Tôi không nghĩ bạn có thể phá vỡ một tên biến, chỉ là một chuỗi.
bgmCoder

19

Bạn có thể sử dụng toán tử backtick:

& "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
    -verb:sync `
    -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" `
    -dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"

Điều đó vẫn còn quá lâu đối với sở thích của tôi, vì vậy tôi sẽ sử dụng một số biến được đặt tên tốt:

$msdeployPath = "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
$verbArg = '-verb:sync'
$sourceArg = '-source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web"'
$destArg = '-dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"'

& $msdeployPath $verbArg $sourceArg $destArg

1
Tôi thích tên biến hơn các đề xuất khác bởi vì nó có thể là tùy chọn dễ đọc nhất cho các chuyên gia không có quyền hạn. Nếu tôi thấy một hướng dẫn / thiết lập hướng dẫn sử dụng tính năng ghép hình, tôi sẽ hoàn toàn lạc lõng với những gì đang diễn ra mà không có hướng dẫn phụ về ghép hình. Tương tự như vậy, backticks có vẻ mong manh và có lẽ ít được biết đến hơn các biến PS thực sự đơn giản và đã thử.
Josh Desmond

13

Nếu bạn có một chức năng:

$function:foo | % Invoke @(
  'bar'
  'directory'
  $true
)

Nếu bạn có một lệnh ghép ngắn :

[PSCustomObject] @{
  Path  = 'bar'
  Type  = 'directory'
  Force = $true
} | New-Item

Nếu bạn có một ứng dụng:

{foo.exe @Args} | % Invoke @(
  'bar'
  'directory'
  $true
)

Hoặc là

icm {foo.exe @Args} -Args @(
  'bar'
  'directory'
  $true
)

3

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

PS> &"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" # Shift+Enter
>>> -verb:sync # Shift+Enter
>>> -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" # Shift+Enter
>>> -dest:contentPath="c:\websites\xxx\wwwroot,computerName=192.168.1.1,username=administrator,password=xxx"

0

Phương pháp Splat với tính toán

Nếu bạn chọn phương pháp splat, hãy cẩn thận với các tính toán được thực hiện bằng các tham số khác. Trong thực tế, đôi khi tôi phải đặt biến trước rồi mới tạo bảng băm. Ngoài ra, định dạng không yêu cầu dấu ngoặc đơn xung quanh giá trị khóa hoặc dấu chấm phẩy (như đã đề cập ở trên).

Example of a call to a function that creates an Excel spreadsheet

$title = "Cut-off File Processing on $start_date_long_str"
$title_row = 1
$header_row = 2
$data_row_start = 3
$data_row_end = $($data_row_start + $($file_info_array.Count) - 1)

# use parameter hash table to make code more readable
$params = @{
    title = $title
    title_row = $title_row
    header_row = $header_row
    data_row_start = $data_row_start
    data_row_end = $data_row_end
}
$xl_wksht = Create-Excel-Spreadsheet @params

Lưu ý: Mảng tệp chứa thông tin sẽ ảnh hưởng đến cách bảng tính được điền.


-1

Một cách khác để ngắt một chuỗi trên nhiều dòng là đặt một biểu thức trống ở giữa chuỗi và ngắt nó qua các dòng:

chuỗi mẫu:

"stackoverflow stackoverflow stackoverflow stackoverflow stackoverflow"

bị đứt ngang

"stackoverflow stackoverflow $(
)stackoverflow stack$(
)overflow stackoverflow"
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.