Powershell: Làm cách nào để ngăn lỗi hiển thị trong tập lệnh?


92

Ví dụ: khi tập lệnh PowerShell của tôi cố gắng tạo một đối tượng SQL Server cho một máy chủ không tồn tại ("bla" trong trường hợp của tôi), PowerShell sẽ hiển thị rất nhiều lỗi PowerShell màu đỏ.

Vì tập lệnh của tôi kiểm tra giá trị của $?sau các cuộc gọi như vậy, và hiển thị và ghi lại các lỗi, tôi không muốn hiển thị một số dòng lỗi PowerShell.

Làm cách nào để hủy kích hoạt những thứ đang được hiển thị cho tập lệnh của tôi?

Câu trả lời:


132

Bạn có một cặp đôi tùy chọn. Dễ nhất là sử dụng các ErrorActioncài đặt.

-Erroractionlà một tham số chung cho tất cả các lệnh ghép ngắn. Nếu có các lệnh đặc biệt bạn muốn bỏ qua, bạn có thể sử dụng lệnh -erroraction 'silentlycontinue'này về cơ bản sẽ bỏ qua tất cả các thông báo lỗi do lệnh đó tạo ra. Bạn cũng có thể sử dụng Ignoregiá trị (trong PowerShell 3+):

Không giống như SilentlyContinue, Bỏ qua không thêm thông báo lỗi vào biến tự động $ Error.

Nếu bạn muốn bỏ qua tất cả các lỗi trong tập lệnh, bạn có thể sử dụng biến hệ thống $ErrorActionPreferencevà làm điều tương tự:$ErrorActionPreference= 'silentlycontinue'

Xem about_CommonParameters để biết thêm thông tin về -ErrorAction. Xem about_preference_variables để biết thêm thông tin về $ ErrorActionPreference.


bạn có cần trích dẫn duy nhất trong -erroraction 'lặng lẽ tiếp tục' không? Intellisese đang hiển thị các tùy chọn và không thêm trích dẫn đơn lẻ.
PAS

1
Nếu định dạng trên không phù hợp với bạn, hãy tham khảo liên kết được cung cấp ở trên. Tôi đã phải định dạng như -ErrorAction:SilentlyContinuetrong PS 5.1. Tôi đã gọi lệnh ghép ngắn của mình từ hàng loạt nên tôi không biết liệu điều đó có tạo ra sự khác biệt hay không. Nhưng thông tin tốt khi bạn biết một lỗi có thể chấp nhận được có thể được ném ra.
David,

--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys

18

Windows PowerShell cung cấp hai cơ chế để báo cáo lỗi: một cơ chế để kết thúc lỗi và một cơ chế khác cho lỗi không kết thúc .

Mã CmdLets nội bộ có thể gọi một ThrowTerminatingErrorphương thức khi xảy ra lỗi không cho phép lệnh ghép ngắn tiếp tục xử lý các đối tượng đầu vào của nó. Trình ghi tập lệnh có thể sử dụng ngoại lệ để bắt những lỗi này không.

VÍ DỤ :

try
{
  Your database code
}
catch
{
  Error reporting/logging
}

Mã CmdLets bên trong có thể gọi một WriteErrorphương thức để báo cáo lỗi không kết thúc khi lệnh ghép ngắn có thể tiếp tục xử lý các đối tượng đầu vào. Người viết kịch bản sau đó có thể sử dụng tùy chọn -ErrorAction để ẩn thông báo hoặc sử dụng tùy chọn này $ErrorActionPreferenceđể thiết lập toàn bộ hành vi của tập lệnh.


8

Tôi đã gặp sự cố tương tự khi cố gắng giải quyết bằng cách sử dụng tên máy chủ [system.net.dns]. Nếu IP không được giải quyết. Net đã gây ra lỗi kết thúc. Để ngăn lỗi kết thúc và vẫn giữ quyền kiểm soát đầu ra, tôi đã tạo một hàm bằng cách sử dụng TRAP.

VÍ DỤ

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}

3

Bạn đang đi chệch hướng ở đây.

Bạn đã có một thông báo lỗi lớn. Tại sao bạn lại muốn viết mã kiểm tra $?rõ ràng sau mỗi lệnh ? Điều này cực kỳ cồng kềnh và dễ xảy ra lỗi. Giải pháp chính xác là dừng kiểm tra$? .

Thay vào đó, hãy sử dụng cơ chế tích hợp của PowerShell để thổi bay cho bạn. Bạn kích hoạt nó bằng cách đặt tùy chọn lỗi ở mức cao nhất:

$ErrorActionPreference = 'Stop'

Tôi đặt điều này ở đầu mỗi kịch bản tôi từng viết và bây giờ tôi không cần phải kiểm tra $?. Điều này làm cho mã của tôi đơn giản hơn và đáng tin cậy hơn.

Nếu bạn gặp phải tình huống mà bạn thực sự cần phải tắt hành vi này, bạn có thể catchbáo lỗi hoặc chuyển một cài đặt cho một chức năng cụ thể bằng cách sử dụng chung -ErrorAction. Trong trường hợp của bạn, bạn có thể muốn quá trình của mình dừng lại ở lỗi đầu tiên, bắt lỗi và sau đó ghi lại lỗi đó.

Lưu ý rằng điều này không xử lý trường hợp khi các tệp thực thi bên ngoài bị lỗi (thoát mã khác không, theo cách thông thường), vì vậy bạn vẫn cần kiểm tra $LASTEXITCODExem bạn có gọi bất kỳ lệnh nào không. Mặc dù có hạn chế này, thiết lập vẫn tiết kiệm rất nhiều mã và công sức.

Độ tin cậy bổ sung

Bạn cũng có thể muốn xem xét sử dụng chế độ nghiêm ngặt :

Set-StrictMode -Version Latest

Điều này ngăn PowerShell tiếp tục âm thầm khi bạn sử dụng một biến không tồn tại và trong các tình huống kỳ lạ khác. (Xem -Versionthông số để biết chi tiết về những gì nó hạn chế.)

Việc kết hợp hai cài đặt này làm cho PowerShell trở thành ngôn ngữ xử lý lỗi nhanh hơn nhiều, giúp việc lập trình trong đó dễ dàng hơn rất nhiều.


2

Thêm -ErrorAction SilentlyContinuevào tập lệnh của bạn và bạn sẽ sẵn sàng.


2

Trong một số trường hợp, bạn có thể đặt sau lệnh là Out-Null

command | Out-Null

-1

Nếu bạn muốn ngăn chặn lỗi sai của powershell đối với lệnh ghép ngắn nhưng vẫn muốn bắt lỗi, hãy sử dụng "-erroraction 'silentStop'"


Không có hành động như vậy. Altough có một hành động Dừng.
Marvin Dickhaus

Nhưng nó cho phép để ngăn chặn thông báo lỗi màu đỏ và vẫn sử dụng catch lệnh / phần khi sử dụng New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager

@MilanKerslager bạn có thể vui lòng hiển thị một mẫu mã không - vì tôi và mọi người khác, tin rằng không có ActionPreference nào là 'SilentlyStop'
FSCKur 22/01/19

Tôi hoàn toàn tin tưởng rằng Mikkel có nghĩa là SilentlyContinue chứ không phải là lặng lẽ Dừng lại, bởi vì điều đó có ý nghĩa hơn rất nhiều trong nội dung của những gì bạn muốn nó làm.
John
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.