2016-09-03 9 views
1

Ich stieß auf dieses seltsame Problem in Powershell (nicht in anderen Sprachen). Könnte mir bitte jemand erklären, warum das passiert ist?Powershell gibt falsches Ergebnis zurück

Ich habe versucht, eine bestimmte Nummer (Nummer 8) zurückgeben, aber die Funktion wirft alles auf mich. Ist das ein Fehler oder ein Design?

Function GetNum() { 
    Return 10 
} 

Function Main() { 

    $Number10 = GetNum 
    $number10 #1 WHY NO OUTPUT HERE ??????? I don't want to use write host 
    $result = 8 # I WANT THIS NUMBER ONLY 
    PAUSE 
    return $result 
} 

do {  
    $again = Main 
    Write-Host "RESULT IS "$again # Weird Result, I only want Number 8 
} While ($again -eq 10) # As the result is wrong, it loops forever 

Antwort

6

Ist das ein Bug oder Design?

Durch Entwurf. In PowerShell können Cmdlets einen Stream von Objekten zurückgeben, ähnlich wie in C# yield return, um eine IEnumerable Sammlung zurückzugeben.

Das Schlüsselwort return ist nicht erforderlich, damit die Ausgabewerte zurückgegeben werden, es gibt einfach den aktuellen Bereich aus (oder gibt von zurück).

Von Get-Help about_Return (Hervorhebung hinzugefügt):

 
    The Return keyword exits a function, script, or script block. It can be 
    used to exit a scope at a specific point, to return a value, or to indicate 
    that the end of the scope has been reached. 


    Users who are familiar with languages like C or C# might want to use the 
    Return keyword to make the logic of leaving a scope explicit. 


    In Windows PowerShell, the results of each statement are returned as 
    output, even without a statement that contains the Return keyword. 
    Languages like C or C# return only the value or values that are specified 
    by the Return keyword. 
4

Mathias ist wie gewohnt vor Ort.

ich diesen Kommentar in Ihrem Code ansprechen wollen:

$number10 #1 WHY NO OUTPUT HERE ??????? I don't want to use write host 

Warum nicht Write-Host verwenden? Liegt es daran, dass Sie auf this very popular post from PowerShell's creator with the provocative title Write-Host Considered Harmful gestoßen sind?

Wenn ja, ich ermutige Sie, zu lesen, was ich denke, ist ein großes Folge-/Stück von tby des Titel Is Write-Host Really Harmful?

Mit diesen Informationen sollte es klar sein, dass, wie Mathias sagte, Sie sind wiederkehrende Objekte zur Pipeline, aber Sie sollten auch mit den Informationen bewaffnet sein, die benötigt werden, um eine Alternative zu wählen, ob es Write-Verbose, Write-Debug oder sogar Write-Host ist.

Wenn ich darüber werden würden opinionated, würde ich mit Write-Verbose gehen, Funktionsdefinition leicht, um zu verändern, sie zu unterstützen:

function Main { 
[CmdletBinding()] 
param() 

    $Number10 = GetNum 
    Write-Verbose -Message $number10 
    $result = 8 # I WANT THIS NUMBER ONLY 
    PAUSE 
    $result 
} 

Wenn Sie es aufrufen, indem nur anrufen $again = Main Sie werden sehen, nichts auf dem Bildschirm, und $again wird einen Wert von 8 haben. Allerdings, wenn Sie es so nennen:

$again = Main -Verbose 

dann $again noch den Wert von 8 haben, aber auf dem Bildschirm werden Sie sehen:

VERBOSE: 10 

wahrscheinlich in unterschiedlich farbigen Text.

Was das gibt nicht nur einen Weg, um den Wert zu zeigen, sondern eine Möglichkeit für den Anrufer zu kontrollieren, ob sie den Wert sehen oder nicht, ohne den Rückgabewert der Funktion zu ändern.

Um einige der Punkte in den Artikeln nach Hause weiter zu fahren, beachten Sie, dass es nicht unbedingt notwendig ist, Ihre Funktion mit -Verbose aufzurufen, um das zu bekommen.

Nehmen wir an, Sie haben das ganze Skript in einer Datei namens FeelingNum.ps1 gespeichert.

Wenn zusätzlich zu den Änderungen, die ich oben gemacht, Sie auch die folgenden an die Spitze der Datei hinzufügen:

[CmdletBinding()] 
param() 

Dann Sie noch Ihre Funktion aufgerufen „normal“ wie $again = Main, könnten Sie noch die ausführliche Ausgabe erhalten, indem Ihr Skript mit -Verbose Aufruf:

powershell.exe -File FeelingNum.ps1 -Verbose 

Was dort passiert ist, dass die -Verbose Parameter mit einer variablen setzt genannt 01.236., und das wird bei jeder aufgerufenen Funktion vererbt (außer es wird überschrieben). Sie können $VerbosePreference auch manuell einstellen.

Also, was Sie mit diesen integrierten Funktionen erhalten, ist eine Menge Flexibilität, sowohl für Sie als Autor und für jeden, der Ihren Code verwendet, der eine gute Sache ist, auch wenn die einzige Person es ist Sie.

+0

Vielen Dank Jungs !!! Ich verstehe jetzt. Es ist ein ziemlich interessantes Konzept, ich habe nicht bemerkt, dass die aufgerufene Funktion in Powershell die Ausgabe jeder Anweisung zurückgibt. –

+1

@ romeo.Do Wir lernen jeden Tag etwas Neues :) In PowerShell 5.0 können Sie auch in den 'Information'-Stream schreiben - wie in Briantists Beispiel, aber stattdessen mit' Write-Information' und '$ InformationPreference' –

Verwandte Themen