फ़ंक्शन रिटर्न मानों की बात आती है जब हम कुछ अजीब PowerShell व्यवहार में आए थे।पावरशेल फ़ंक्शन रिटर्न मान का अप्रत्याशित व्यवहार
कुछ संदर्भ:
हमारे स्क्रिप्ट और मॉड्यूल में, हम हमेशा एक वैश्विक डिफ़ॉल्ट कि एक समारोह के साथ पुनः प्राप्त करने योग्य है $ErrorActionPreference
और $DebugPreference
सेट करना चाहते हैं। आइए मान लें कि हम अपने लॉग में अतिरिक्त संदेश रखने के लिए $DebugPreference
"Continue"
पर सेट करना चाहते हैं।
तो, हम इस तरह somthing कर रहे हैं:
$DebugPreference = Get-GlobalDebugPreference
क्या यह एक अच्छा दृष्टिकोण है या नहीं इस सवाल का हिस्सा नहीं है।
समस्या:
PowerShell के विभिन्न संस्करणों यह सिर्फ अपेक्षा के अनुरूप काम नहीं किया था के साथ कुछ मशीनों पर। जब हमने अपनी समारोह है कि रिटर्न "Continue
", $DebugPreference
वास्तव में था सही मान संग्रहीत कहा जाता है, लेकिन हम अपने लॉग फ़ाइल में किसी भी अतिरिक्त लॉग संदेशों नहीं था
क्या हमें पता चला:।
चाहे Write-Debug
हमारे ग्लोबल डिफॉल्ट प्रबंधित करने वाले फ़ंक्शन से " "Continue
" मान को वापस करने के तरीके से काम करता है या नहीं।
उदा। जब समारोह निम्न उदाहरण की तरह दिखता है, राईट-डीबग बर्ताव की उम्मीद और PowerShell 3. में प्रिंट डिबग संदेशों PowerShell 2 हालांकि, मूल्य "Continue
के लिए निर्धारित है के रूप में ", लेकिन राईट-डीबग अतिरिक्त संदेशों को मुद्रित नहीं करता है।
function Get-GlobalDebugPreference
{
return "Continue"
}
$DebugPreference = Get-GlobalDebugPreference
हालांकि, अगर हम सिर्फ खोल पर मूल्य ड्रॉप और return
बयान को छोड़ देते हैं, इसके बारे में PowerShell v2 + सभी संस्करणों के लिए काम करता है।
function Get-GlobalDebugPreference
{
"Continue"
}
$DebugPreference = Get-GlobalDebugPreference
वहाँ PowerShell में एक समारोह से एक मूल्य के वापस जाने के लिए कई तरीके हैं कुछ तरीकों से यह पीएस संस्करण 2 के लिए काम करता है, कुछ v3 के साथ काम करते हैं। Howe मूल्य "Continue
मान वापस करने के लिए लिखें-आउटपुट का उपयोग करते हुए "v5 तक काम नहीं करता है।
मेरी राय में, सभी अलग-अलग दृष्टिकोणों को ठीक काम करना चाहिए और उन्हें अदला-बदली होना चाहिए। कि इस तरह की बुनियादी चीजों के लिए व्यवहार अलग है और PowerShell कुछ हद तक अप्रत्याशित बनाता है।
मैंने एक छोटी सी लिपि तैयार की जो $DebugPreference
को फ़ंक्शन रिटर्न के विभिन्न दृष्टिकोणों के साथ सेट करता है जो सभी समान व्यवहार करते हैं। यदि आप इसे PowerShell के विभिन्न संस्करणों के साथ चलाते हैं तो आपको डीबग आउटपुट की अलग-अलग मात्रा मिलती है। ध्यान दें कि परिवर्तनीय $DebugPreference
में प्रत्येक चरण के बाद सही मान और सही प्रकार है, लेकिन लिखें-डीबग केवल उनमें से कुछ के बाद ही काम करता है।
कोई बता सकता है कि यहां क्या हो रहा है?
"powershell.exe -version 2 ...
के साथ चल रहा है "मुझे इस उत्पादन देता है:
Starting to test return values. Current DebugPreference: SilentlyContinue
1 Obtained the value with return: Continue with Type string
2 Obtained the value from shell with return after: Continue with Type string
DEBUG: 2 After Get-GlobalDefaultWithReturnAfterwards
3 Obtained the value from shell with return after: Continue with Type System.Management.Automation.ActionPreference
DEBUG: 3 After Get-GlobalDefaultWithReturnAfterwardsActionPreference
4 Obtained the value without return: Continue with Type string
DEBUG: 4 After Get-GlobalDefaultWithOutReturn
5 Obtained the value with Write-Output: Continue with Type string
6 Obtained the value with Write-Output: Continue with Type System.Management.Automation.ActionPreference
7 Obtained piped value with Write-Output : Continue with Type string
8 Set the value directly: Continue with Type string
DEBUG: 8 After setting the value directly
"powershell.exe -version 5 ...
के साथ चल रहा है":
Starting to test return values. Current DebugPreference: SilentlyContinue
1 Obtained the value with return: Continue with Type string
DEBUG: 1 After Get-GlobalDefaultWithReturn
2 Obtained the value from shell with return after: Continue with Type string
DEBUG: 2 After Get-GlobalDefaultWithReturnAfterwards
3 Obtained the value from shell with return after: Continue with Type System.Management.Automation.ActionPreference
DEBUG: 3 After Get-GlobalDefaultWithReturnAfterwardsActionPreference
4 Obtained the value without return: Continue with Type string
DEBUG: 4 After Get-GlobalDefaultWithOutReturn
5 Obtained the value with Write-Output: Continue with Type string
6 Obtained the value with Write-Output: Continue with Type System.Management.Automation.ActionPreference
DEBUG: 6 After Get-GlobalDefaultWriteOutputActionPreference
7 Obtained piped value with Write-Output : Continue with Type string
8 Set the value directly: Continue with Type string
DEBUG: 8 After setting the value directly
स्क्रिप्ट:
function Get-GlobalDefaultWithReturn
{
return "Continue"
}
function Get-GlobalDefaultWithReturnAfterwards
{
"Continue"
return
}
function Get-GlobalDefaultWithReturnAfterwardsActionPreference
{
([System.Management.Automation.ActionPreference]::Continue)
return
}
function Get-GlobalDefaultWithOutReturn
{
"Continue"
}
function Get-GlobalDefaultWriteOutput
{
Write-Output "Continue"
}
function Get-GlobalDefaultWriteOutputActionPreference
{
Write-Output ([System.Management.Automation.ActionPreference]::Continue)
}
$DebugPreference = "SilentlyContinue"
Write-Host "Starting to test return values. Current DebugPreference: $DebugPreference"
$DebugPreference = Get-GlobalDefaultWithReturn
Write-Host "1 Obtained the value with return: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "1 After Get-GlobalDefaultWithReturn"
$DebugPreference = "SilentlyContinue"
$DebugPreference = Get-GlobalDefaultWithReturnAfterwards
Write-Host "2 Obtained the value from shell with return after: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "2 After Get-GlobalDefaultWithReturnAfterwards"
$DebugPreference = "SilentlyContinue"
$DebugPreference = Get-GlobalDefaultWithReturnAfterwardsActionPreference
Write-Host "3 Obtained the value from shell with return after: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "3 After Get-GlobalDefaultWithReturnAfterwardsActionPreference"
$DebugPreference = "SilentlyContinue"
$DebugPreference = Get-GlobalDefaultWithOutReturn
Write-Host "4 Obtained the value without return: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "4 After Get-GlobalDefaultWithOutReturn"
$DebugPreference = "SilentlyContinue"
$DebugPreference = Get-GlobalDefaultWriteOutput
Write-Host "5 Obtained the value with Write-Output: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "5 After Get-GlobalDefaultWriteOutput"
$DebugPreference = "SilentlyContinue"
$DebugPreference = Get-GlobalDefaultWriteOutputActionPreference
Write-Host "6 Obtained the value with Write-Output: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "6 After Get-GlobalDefaultWriteOutputActionPreference"
$DebugPreference = "SilentlyContinue"
Get-GlobalDefaultWriteOutput | % { $DebugPreference = $_ }
Write-Host "7 Obtained piped value with Write-Output : $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "7 After Get-GlobalDefaultWriteOutput with pipe"
$DebugPreference = "SilentlyContinue"
$DebugPreference = "Continue"
Write-Host "8 Set the value directly: $DebugPreference with Type $($DebugPreference.GetType())"
Write-Debug "8 After setting the value directly"
यह v5 से पहले PowerShell में एक बग जैसा दिखता है। फ़ंक्शन लौटने वाले डिफ़ॉल्ट आउटपुट और 'लिखें-आउटपुट'/'echo' आउटपुट के बीच कोई अंतर नहीं होना चाहिए। यदि आप '$ DebugPreference' के बजाय' $ global: DebugPreference' को संशोधित करते हैं तो आपको सही परिणाम मिलते हैं। –
अनुपूरक: 'वापसी "जारी रखें" वांछित परिणाम नहीं होने पर एक बग प्रतीत होता है जो PowerShell v3 में तय किया गया था। –