2010-05-04 33 views
7

Có thể kiểm tra sự tồn tại của một biến có phạm vi kịch bản trong PowerShell không?Làm thế nào để kiểm tra sự tồn tại của một biến kịch bản phạm vi trong PowerShell?

Tôi đã sử dụng các PowerShell Community Extensions (PSCX) nhưng tôi đã nhận thấy rằng nếu bạn nhập các module trong khi Set-PSDebug -Strict được thiết lập, một lỗi được sản xuất:

The variable '$SCRIPT:helpCache' cannot be retrieved because it has not been set. 
At C:\Users\...\Modules\Pscx\Modules\GetHelp\Pscx.GetHelp.psm1:5 char:24 

Trong khi điều tra làm thế nào tôi có thể khắc phục điều này, tôi thấy điều này đoạn mã trong Pscx.GetHelp.psm1:

#requires -version 2.0 

param([string[]]$PreCacheList) 

if ((!$SCRIPT:helpCache) -or $RefreshCache) { 
    $SCRIPT:helpCache = @{} 
} 

Đây là mã khá thẳng về phía trước; nếu bộ nhớ cache không tồn tại hoặc cần được làm mới, hãy tạo bộ nhớ cache mới, trống. Vấn đề là gọi $SCRIPT:helpCache trong khi Set-PSDebug -Strict có hiệu lực sẽ xảy ra lỗi do biến chưa được xác định.

Lý tưởng nhất, chúng tôi có thể sử dụng lệnh ghép ngắn Test-Variable nhưng một thứ như vậy không tồn tại! Tôi nghĩ về việc tìm kiếm nhà cung cấp variable: nhưng tôi không biết cách xác định phạm vi của một biến.

Vì vậy, câu hỏi của tôi là: làm thế nào tôi có thể kiểm tra sự tồn tại của một biến trong khi Set-PSDebug -Strict có hiệu lực, mà không gây ra lỗi?

+3

Nếu bạn đang sử dụng PowerShell 2.0, tôi khuyên bạn nên sử dụng 'Set-StrictMode -version 2.0' vì nó sẽ phát hiện thêm các vấn đề tiềm ẩn. –

Trả lời

5

Sử dụng test-path variable:SCRIPT:helpCache

if (!(test-path variable:script:helpCache)) { 
    $script:helpCache = @{} 
} 

này làm việc cho tôi không có vấn đề. kiểm tra sử dụng mã này:

@' 
Set-PsDebug -strict 
write-host (test-path variable:script:helpCache) 
$script:helpCache = "this is test" 
write-host (test-path variable:script:helpCache) and value is $script:helpCache 
'@ | set-content stricttest.ps1 

.\stricttest.ps1 
+0

Tôi đã thêm một ví dụ thực sự hiệu quả với tôi. Nếu bạn có bất kỳ vấn đề gì, tôi cần phải biết vấn đề là gì;) – stej

+2

Đây có lẽ là cách tốt nhất. Bí quyết với [h] elpCache là nhanh hơn (chỉ một chút) nhưng nó là hacky. Ngoài ra, cách kiểm tra đường dẫn tốt hơn nhiều khi tên của biến là một biến tự, tức là biến Test-Path: script: $ name –

+0

FWIW, sử dụng 'biến đường dẫn thử nghiệm:' là phương pháp chúng tôi thường sử dụng trong PSCX. Tôi sẽ xem xét vấn đề này tối nay. –

1

Bạn có thể sử dụng Get-Variable với tham số -Scope. Lệnh này sẽ (theo mặc định ít nhất) không trở về chỉ có giá trị của biến nhưng một đối tượng PSVariable và sẽ ném một ngoại lệ nếu biến không được tìm thấy:

Get-Variable foo -Scope script 
+0

@Johannes Cảm ơn bạn đã trả lời. Đó là ngoại lệ được ném bởi 'Get-Variable' mà tôi đang cố gắng tránh. Tôi có thể làm điều đó với 'try/catch' rõ ràng, nhưng tôi muốn biết nếu có một cách dễ đọc hơn mà không tách văn bản màu đỏ vào cửa sổ đầu ra của tôi. :) –

+0

* Get-Variable -ErrorAction SilentlyContinue * nên thực hiện thủ thuật. Bạn có thể kiểm tra kết quả của lệnh gọi. N.B. Tuy nhiên, lỗi này vẫn được thêm vào danh sách $ Error. –

+0

@Roman Kuzmin Thủ thuật '-ErrorAction' không giúp ích gì. Xấu hổ, bởi vì điều đó có vẻ như là một giải pháp tốt. –

4

Hãy thử mẹo này:

Get-Variable [h]elpCache -Scope Script 

Nó không nên ném hoặc phát ra bất kỳ lỗi nào vì chúng tôi sử dụng một ký tự đại diện [h]elpCache. Mặt khác, loại ký tự đại diện này là một tên theo nghĩa đen.

+0

Đó là một cách gọn gàng :-) – Joey

+2

Vâng, theo cách này là hacky. @stej đề xuất một giải pháp tốt hơn. Tuy nhiên, mẹo với ký tự đại diện giả là hữu ích trong nhiều trường hợp, ví dụ: cho Get-Process (không có thay thế Test-Path cho các quá trình). –

+0

Đó chắc chắn là một mẹo tôi sẽ nhớ. –

Các vấn đề liên quan