2017-07-24 9 views
5

फ़ंक्शन रिटर्न मानों की बात आती है जब हम कुछ अजीब 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" 
+1

यह v5 से पहले PowerShell में एक बग जैसा दिखता है। फ़ंक्शन लौटने वाले डिफ़ॉल्ट आउटपुट और 'लिखें-आउटपुट'/'echo' आउटपुट के बीच कोई अंतर नहीं होना चाहिए। यदि आप '$ DebugPreference' के बजाय' $ global: DebugPreference' को संशोधित करते हैं तो आपको सही परिणाम मिलते हैं। –

+0

अनुपूरक: 'वापसी "जारी रखें" वांछित परिणाम नहीं होने पर एक बग प्रतीत होता है जो PowerShell v3 में तय किया गया था। –

उत्तर

1

इससे पहले मैं मुझे इस उत्पादन देता है ने कहा कि मेरे पास समस्या नहीं थी लेकिन ऐसा लगता है कि जिस तरह से आप दौड़ते हैं कोड मामलों, के रूप में वी 2 यह है कि क्या मैं पता चला है चल आईएसई, कंसोल और उच्चतर Powershell संस्करणों को छोड़कर:

समस्या के बिना:

  • PowerShell.exe -file c: \ debugtest.ps1
  • Powershell। exe -command "c: \ debugtest.ps1"।:

    • PowerShell.exe -command ग
    समस्या के साथ

    : \ Debugtest.ps1

वैकल्पिक हल मैं सुझाव दिया था कि इस मामले में काम:

आप का प्रयास करना चाहें (Get-GlobalDefaultWithReturn) .tostring() यह एक स्ट्रिंग है कि अगर करने के लिए मजबूर करने के लिए मुद्दा है

Powershell संस्करण:

Major Minor Build Revision 
----- ----- ----- -------- 
2  0  -1  -1  

यह एक बग की तरह दिखता है, लेकिन मैं अभी तक इस बारे में अधिक कुछ भी पता नहीं है। सच है कि यह थोड़ा अप्रत्याशित है लेकिन आप अपना कोड चलाने के तरीके पर विचार करना चाहेंगे, उदा। FILE के साथ अगर यह एक फ़ाइल है।

+0

मैं पावरशेल v4 स्थापित सिस्टम पर 'powerhell -version 2' के साथ वर्णित व्यवहार को पुन: पेश कर सकता हूं। मेरे पास यहां एक शुद्ध पावरशेल v2 प्रणाली नहीं है। आज रात बाद में सत्यापित करेंगे। –

+1

XP परीक्षण बॉक्स पर PowerShell v2 समान व्यवहार दिखाता है जैसे '-version 2' के साथ एक नया संस्करण चला रहा है। –

संबंधित मुद्दे