Unterstützende Ressource

Unterstützende Ressource

Angenommen, ich habe ein einfaches test.ps1:

Write-Host "access input for the 1st time: $input"
Write-Host "access input for the 2nd time: $input"

Dann mach ich'foo' | .\test.ps1

Gibt aus:

1. Mal auf die Eingabe zugreifen: foo
2. Mal auf die Eingabe zugreifen:

Nach $inputeinmaligem Zugriff ist der Wert weg. Warum?

Der Arztsagt, es liegt daran, dass $input ein Enumerator ist:

Da $input ein Enumerator ist, führt der Zugriff auf eine seiner Eigenschaften dazu, dass $input nicht mehr verfügbar ist. Sie können $input in einer anderen Variable speichern, um die $input-Eigenschaften wiederzuverwenden.

Aber ich verstehe nicht, was es bedeutet, ein Zähler zu sein.

Soweit ich weiß, wird die Liste nicht aufgezählt, wenn ich eine Liste von Dingen einleite, da ich keinen process{}Block habe. Wenn ich beispielsweise einen Block habe @(1,2,3) | .\test.ps1, wird mein Code nur einmal ausgeführt und das Array wird als einzelnes Objekt behandelt.

Zugangseingabe zum 1. Mal: ​​1 2 3
Zugangseingabe zum 2. Mal:

Ich verstehe also nicht, was aufgezählt wird und warum $input ein Enumerator ist.

Antwort1

Sie müssen den Rest der Beschreibung berücksichtigen und vielleicht nachlesenabout_Functions_AdvancedUndüber_Funktionen_Erweiterte_Methoden.

Ihr Beispiel ergibt einfach nicht viel Sinn. Der Aufruf des Skripts funktioniert als anonyme Funktion. Da Sie es nur $inputim ersten Fall verwenden lassen, passiert Folgendes:

In einer Funktion ohne Begin-, Process- oder Endblock zählt die Variable $input die Sammlung aller Eingaben für die Funktion auf.

Write-Hostakzeptiert die Aufzählung und iteriert sie. Daher erhalten Sie scheinbar nur einen einzigen Wert. Im Wesentlichen ruft es ".toString()" darauf auf.

Bei Verwendung einer Schleife werden Sie feststellen, dass Sie einzelne Werte erhalten.

$counter = 0;
$input | ForEach-Object {
    Write-Host "access input for the $counter time: $_"
    $counter = $counter + 1
}

Wenn Sie diese Funktionalität benötigen, ist es wahrscheinlich besser, einen Prozessblock zu verwenden. Weitere Informationen dazu finden Sie in der erweiterten Funktionshilfe.

begin {
    $counter = 0
}
process {
    Write-Host "access input for the $counter time: $_"
    $counter = $counter + 1
}

Beachten Sie, dass sich in diesem Fall die Funktionsweise $inputgeringfügig ändert.

Gemäß derInformationen zu ZählernNormalerweise ist es besser, reguläre Funktionsparameter mit einer geeigneten Definition zu haben, als direkt mit zu arbeiten $input.

Antwort2

Iterieren Sie über eine Liste von Dingen, indem Sie dieListehinüber zu einemforeach-objectSchleife mit dem Skript-/Funktionsaufruf darin scriptblock.

Leiten Sie darin scriptblockden iterierten Wert an den Funktionsaufruf weiter alsEingangum den erwarteten Wert pro Aufruf gemäß dem zurückgegebenen Ausgabewert zu erhalten.

Bei dieser PowerShell-Lösung ist die Skriptlogik verpackt ineinfache FunktionAnweisungsblock, und Sie müssen den Write-OutputCode nicht mehr als einmal wiederholen – Standard, Einfach und Grundlegend.

Daher besteht hinsichtlich des process{}Blocks kein Grund zur besonderen Sorge.

PowerShell Test.ps1-Skript

Function Test {
    Write-Output "Access to your mom's: $input"
    };

Power ShellPunktquelleSkript und rufe es auf

. "$Env:USERPROFILE\Desktop\test.ps1"
@("car","house","bank account") | % { $_ | test  }

Ausgabe

Access to your mom's: car
Access to your mom's: house
Access to your mom's: bank account

Logikaufschlüsselung

Bildbeschreibung hier eingeben

Aber ich verstehe nicht, was es bedeutet, ein Zähler zu sein.

Darüber hinaus gemäß$inputStellungnahmeWie unten referenziert und zitiert, bedeutet dies, dass es der Platzhalter für den als Eingabe übergebenen Eingabewert sein wird, sodass dieser übergebene Wert aufgezählt wird. Sie verwenden es $inputim Skript und es enthält den Wert, den es als Eingabe erhalten hat. Das Problem, das Sie hatten, war, dass alle Werte gemäß diesen Methoden als eine lange, zusammengesetzte Zeichenfolge übergeben wurden.

  • Enthält einen Enumerator, der alle an eine Funktion übergebenen Eingaben aufzählt. Die $inputVariable ist nur für Funktionen und Skriptblöcke (die unbenannte Funktionen sind) verfügbar.

    Quelle

Auch, die andere Aussage, die Sie nicht verstanden haben, besagt ledigliches [ $input] hält diesen Wert nur in der Instanz, in der es aufgerufen wird. Sie können damit $inputvor oder nach dem Aufruf keinen Wert abrufen, es wird lediglich beim Aufruf auf einen als Eingabe dienenden Wert gesetzt.

Schließlich können Sie eine Variable bei einem Funktionsaufruf festlegenum Ihnen die Ausgabe zu geben, die $inputbeim Aufruf „aufgezählt“ wurde (also $var = "jewelry box" | test). Das bedeutet, dass die Variable anschließend außerhalb des Aufrufs mit dem Wert verfügbar ist, $inputden sie bei der Ausführung hatte.

Andere mögliche Bonuslösungen

## Input piped to script function call
@("car","house","bank account").ForEach( {$_ | test} );

## Uses "$_" as the placeholder to contain the value iterated right to the command no script or function needed
@("car","house","bank account").ForEach( { Write-Output "Access to your mom's: $_" } );

Unterstützende Ressource

verwandte Informationen