Szukaj…


Wprowadzenie

PowerShell wprowadza model potokowania obiektów, który umożliwia wysyłanie całych obiektów w dół potoku do zużywających się komend lub (przynajmniej) danych wyjściowych. W przeciwieństwie do klasycznego potoku opartego na łańcuchach, informacje w obiektach potokowych nie muszą znajdować się w określonych pozycjach. Komendy mogą zadeklarować interakcję z obiektami z potoku jako danych wejściowych, a zwracane wartości są automatycznie przesyłane do potoku.

Składnia

  • POCZĄTEK Pierwszy blok. Wykonany raz na początku. Dane wejściowe potoku mają tutaj wartość $ null, ponieważ nie zostały ustawione.
  • PROCES Drugi blok. Wykonane dla każdego elementu potoku. Parametr potoku jest równy aktualnie przetwarzanemu elementowi.
  • END Ostatni blok. Wykonany raz na końcu. Parametr potoku jest równy ostatniemu elementowi wejścia, ponieważ nie został zmieniony od czasu jego ustawienia.

Uwagi

W większości przypadków wejście potoku będzie tablicą obiektów. Chociaż zachowanie bloku PROCESS{} może wydawać się podobne do bloku foreach{} , pomijanie elementu w tablicy wymaga innego procesu.

Jeśli, podobnie jak w foreach{} , użyłeś opcji continue wewnątrz bloku PROCESS{} , spowodowałoby to przerwanie potoku, pomijając wszystkie poniższe instrukcje, w tym blok END{} . Zamiast tego użyj return - zakończy tylko blok PROCESS{} dla bieżącego elementu i przejdzie do następnego.

W niektórych przypadkach istnieje potrzeba wyprowadzenia wyniku funkcji z innym kodowaniem. Kodowanie danych wyjściowych CmdLets jest kontrolowane przez zmienną $OutputEncoding . Jeśli dane wyjściowe są przeznaczone do umieszczenia w potoku do aplikacji rodzimych, dobrym pomysłem może być poprawienie kodowania, aby było zgodne z celem $OutputEncoding = [Console]::OutputEncoding

Dodatkowe referencje:

Artykuł na blogu zawierający więcej informacji na temat $OutputEncoding https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/

Pisanie funkcji z zaawansowanym cyklem życia

Ten przykład pokazuje, w jaki sposób funkcja może akceptować dane potokowe i wykonywać iteracje skutecznie.

Uwaga, że begin i end struktury funkcji podczas odbierania wiadomości jest opcjonalne, ale process jest niezbędne przy korzystaniu ValueFromPipeline lub ValueFromPipelineByPropertyName .

function Write-FromPipeline{
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        $myInput
    )
    begin {
        Write-Verbose -Message "Beginning Write-FromPipeline" 
    }
    process {
        Write-Output -InputObject $myInput
    }
    end {
        Write-Verbose -Message "Ending Write-FromPipeline"
    }
}

$foo = 'hello','world',1,2,3

$foo | Write-FromPipeline -Verbose

Wynik:

VERBOSE: Beginning Write-FromPipeline
hello
world
1
2
3
VERBOSE: Ending Write-FromPipeline

Podstawowe wsparcie rurociągów w funkcjach

To jest przykład funkcji z najprostszym możliwym wsparciem dla rurociągów.
Każda funkcja z obsługą potoku musi mieć co najmniej jeden parametr z ValueFromPipeline ParameterAttribute ValueFromPipeline lub ValueFromPipelineByPropertyName , jak pokazano poniżej.

function Write-FromPipeline {
    param(
        [Parameter(ValueFromPipeline)]  # This sets the ParameterAttribute
        [String]$Input
    )
    Write-Host $Input
}

$foo = 'Hello World!'

$foo | Write-FromPipeline

Wynik:

Hello World!

Uwaga: W programie PowerShell 3.0 i nowszych obsługiwane są Domyślne wartości parametru ParameterAttributes. We wcześniejszych wersjach musisz podać wartość ValueFromPipeline=$true .

Robocza koncepcja rurociągu

W serii potoków każda funkcja działa równolegle do innych, podobnie jak wątki równoległe. Pierwszy przetworzony obiekt jest przesyłany do następnego potoku, a następne przetwarzanie jest natychmiast wykonywane w innym wątku. To tłumaczy szybki wzrost prędkości w porównaniu ze standardowym ForEach

@( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5
  1. krok - skopiuj pierwszy plik (w wątku Copy-file )
  2. krok - skopiuj drugi plik (w wątku Copy-file ) i jednocześnie Zaszyfruj pierwszy Copy-file (w Encrypt-File )
  3. krok - skopiuj trzeci plik (w wątku Copy-file ) i jednocześnie zaszyfruj drugi plik (w Encrypt-File ) i jednocześnie get-Md5 pierwszego (w Get-Md5 )


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow