about_Pipelines

Rövid leírás

Parancsok egyesítése folyamatokba a PowerShellben

Hosszú leírás

A folyamat a folyamatkezelők (|ASCII 124) által csatlakoztatott parancsok sorozata. Minden folyamatüzemeltető elküldi az előző parancs eredményeit a következő parancsnak.

Az első parancs kimenete elküldhető feldolgozásra a második parancs bemeneteként. Ez a kimenet pedig elküldhető egy másik parancsnak. Az eredmény egy összetett parancslánc vagy folyamat , amely egyszerű parancsok sorozatából áll.

Például:

Command-1 | Command-2 | Command-3

Ebben a példában a rendszer elküldi a kibocsátott objektumokatCommand-1.Command-2 Command-2 feldolgozza az objektumokat, és elküldi őket a következőnek Command-3: . Command-3 feldolgozza az objektumokat, és elküldi őket a folyamatba. Mivel nincs több parancs a folyamatban, az eredmények megjelennek a konzolon.

A folyamatokban a parancsok feldolgozása balról jobbra haladva történik. A feldolgozás egyetlen műveletként van kezelve, és a kimenet a létrehozáskor jelenik meg.

Íme egy egyszerű példa. Az alábbi parancs lekéri a Jegyzettömb folyamatot, majd leállítja azt.

Például:

Get-Process notepad | Stop-Process

Az első parancs a parancsmagot használja a Get-Process Jegyzettömb folyamatot képviselő objektum lekéréséhez. Egy folyamatkezelővel (|) küldi el a folyamatobjektumot a Stop-Process parancsmagnak, amely leállítja a Jegyzettömb folyamatot. Figyelje meg, hogy a Stop-Process parancs nem rendelkezik név- vagy azonosítóparaméterrel a folyamat megadásához, mivel a megadott folyamatot a rendszer a folyamaton keresztül küldi el.

Ez a folyamat példája beolvasja az aktuális könyvtárban lévő szövegfájlokat, csak a 10 000 bájtnál hosszabb fájlokat választja ki, hossz szerint rendezi őket, és megjeleníti az egyes fájlok nevét és hosszát egy táblázatban.

Get-ChildItem -Path *.txt |
  Where-Object {$_.length -gt 10000} |
    Sort-Object -Property length |
      Format-Table -Property name, length

Ez a folyamat négy parancsból áll a megadott sorrendben. Az alábbi ábrán az egyes parancsok kimenete látható, miközben a folyamat következő parancsának továbbítja.

Get-ChildItem -Path *.txt
| (FileInfo objects for *.txt)
V
Where-Object {$_.length -gt 10000}
| (FileInfo objects for *.txt)
| (      Length > 10000      )
V
Sort-Object -Property Length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
V
Format-Table -Property name, length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
| (   Formatted in a table   )
V

Name                       Length
----                       ------
tmp1.txt                    82920
tmp2.txt                   114000
tmp3.txt                   114000

Folyamatok használata

A Legtöbb PowerShell-parancsmag a folyamatok támogatására lett tervezve. A legtöbb esetben a Get parancsmag eredményeit egy másik, azonos főnévvel rendelkező parancsmagba is be lehet csövezni. A parancsmag kimenetét Get-Service például a parancsmagokra vagy Stop-Service parancsmagokra Start-Service is be lehet csövezni.

Ez a példafolyamat elindítja a WMI szolgáltatást a számítógépen:

Get-Service wmi | Start-Service

Egy másik példaként a PowerShell beállításjegyzék-szolgáltatójának kimenetét Get-ItemGet-ChildItem a parancsmagra New-ItemProperty is átirányíthatja. Ez a példa egy új, 8124-es értékű NoOfEmployees beállításjegyzék-bejegyzést ad hozzá a MyCompany beállításkulcshoz.

Get-Item -Path HKLM:\Software\MyCompany |
  New-ItemProperty -Name NoOfEmployees -Value 8124

Számos segédprogram-parancsmagot, például Get-Member, Where-Object, Sort-Object, Group-ObjectMeasure-Object és szinte kizárólag folyamatokban használják. Ezekhez a parancsmagokhoz bármilyen objektumtípust be lehet csövezni. Ez a példa bemutatja, hogyan rendezheti a számítógépen lévő összes folyamatot az egyes folyamatokban megnyitott fogópontok száma alapján.

Get-Process | Sort-Object -Property handles

Az objektumokat a formázási, exportálási és kimeneti parancsmagokhoz, például Format-List, Format-Table, Export-Clixml, Export-CSVés Out-File.

Ez a példa bemutatja, hogyan jeleníthető meg a Format-List parancsmag egy folyamatobjektum tulajdonságainak listájával.

Get-Process winlogon | Format-List -Property *

A natív parancsok kimenetét a PowerShell-parancsmagokra is átirányíthatja. Példa:

PS> ipconfig.exe | Select-String -Pattern 'IPv4'

   IPv4 Address. . . . . . . . . . . : 172.24.80.1
   IPv4 Address. . . . . . . . . . . : 192.168.1.45
   IPv4 Address. . . . . . . . . . . : 100.64.108.37

Fontos

A Siker és hiba streamek hasonlóak a többi rendszerhéj stdin és stderr streamjeihez. Az stdin azonban nincs csatlakoztatva a PowerShell-folyamathoz bemenet céljából. További információ: about_Redirection.

Egy kis gyakorlással azt tapasztalhatja, hogy az egyszerű parancsok folyamatokba való kombinálása időt és gépelést takarít meg, és hatékonyabbá teszi a szkriptek használatát.

Folyamatok működése

Ez a szakasz bemutatja, hogyan vannak a bemeneti objektumok a parancsmag paramétereihez kötve, és hogyan dolgozhatók fel a folyamat végrehajtása során.

Folyamatbemenet elfogadása

A pipelining támogatásához a fogadó parancsmagnak rendelkeznie kell egy olyan paraméterrel, amely elfogadja a folyamatbemenetet. Get-Help A parancs a Teljes vagy a Paraméter beállítással határozza meg, hogy a parancsmag mely paraméterei fogadják el a folyamatbemenetet.

Ha például meg szeretné állapítani, hogy a parancsmag mely paraméterei fogadják el a Start-Service folyamatbemenetet, írja be a következőt:

Get-Help Start-Service -Full

vagy

Get-Help Start-Service -Parameter *

A parancsmag súgója Start-Service azt mutatja, hogy csak az InputObject és a Name paraméterek fogadják el a folyamatbemenetet.

-InputObject <ServiceController[]>
Specifies ServiceController objects representing the services to be started.
Enter a variable that contains the objects, or type a command or expression
that gets the objects.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByValue)
Accept wildcard characters?  false

-Name <String[]>
Specifies the service names for the service to be started.

The parameter name is optional. You can use Name or its alias, ServiceName,
or you can omit the parameter name.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByPropertyName, ByValue)
Accept wildcard characters?  false

Amikor objektumokat küld a folyamaton Start-Servicekeresztül, a PowerShell megpróbálja társítani az objektumokat az InputObject és a Name paraméterekkel.

Folyamatbemenet elfogadásának módszerei

A parancsmagok paraméterei kétféleképpen fogadhatják el a folyamatbemenetet:

  • ByValue: A paraméter olyan értékeket fogad el, amelyek megfelelnek a várt .NET-típusnak, vagy amelyek átalakíthatók erre a típusra.

    A folyamatbemenetet például érték szerint fogadja el a Név paraméter Start-Service . Sztringobjektumokat vagy sztringekké konvertálható objektumokat is elfogad.

  • ByPropertyName: A paraméter csak akkor fogadja el a bemenetet, ha a bemeneti objektumnak ugyanaz a tulajdonsága, mint a paraméternek.

    A Név paraméter Start-Service például elfogadhat névtulajdonságú objektumokat. Egy objektum tulajdonságainak listázásához a következőre kell csöveznie Get-Member: .

Egyes paraméterek érték vagy tulajdonságnév alapján is elfogadhatnak objektumokat, így egyszerűbben lehet bemenetet felvenni a folyamatból.

Paraméterkötés

Amikor egy parancsból egy másik parancsba irányítja az objektumokat, a PowerShell megpróbálja társítani a vezetékes objektumokat a fogadó parancsmag egyik paraméterével.

A PowerShell paraméterkötési összetevője a bemeneti objektumokat a parancsmag paramétereivel társítja az alábbi feltételek szerint:

  • A paraméternek fogadnia kell egy folyamat bemenetét.
  • A paraméternek el kell fogadnia az elküldött objektum típusát, vagy a várt típusra konvertálható típust.
  • A paraméter nem lett használva a parancsban.

A parancsmagnak például Start-Service számos paramétere van, de csak kettő, a Név és az InputObject fogadja el a folyamatbemenetet. A Név paraméter sztringeket, az InputObject paraméter pedig szolgáltatásobjektumokat vesz fel. Ezért sztringeket, szolgáltatásobjektumokat és objektumokat csövezhet sztringekké vagy szolgáltatásobjektumokká konvertálható tulajdonságokkal.

A PowerShell a lehető leghatékonyabban kezeli a paraméterkötést. A PowerShell nem javasolható és nem kényszeríthető egy adott paraméterhez való kötésre. A parancs meghiúsul, ha a PowerShell nem tudja kötni a vezetékes objektumokat.

A kötési hibák elhárításával kapcsolatos további információkért tekintse meg a folyamathibák kivizsgálását a cikk későbbi részében.

Egyszeri feldolgozás

Az objektumok parancshoz való pipálása olyan, mintha a parancs egy paraméterét használva küldi el az objektumokat. Tekintsünk meg egy folyamat példáját. Ebben a példában egy folyamat használatával jelenítjük meg a szolgáltatásobjektumok tábláját.

Get-Service | Format-Table -Property Name, DependentServices

Funkcionálisan ez olyan, mintha az InputObject paraméterrel Format-Table küldi el az objektumgyűjteményt.

A szolgáltatások gyűjteményét például menthetjük egy olyan változóba, amely az InputObject paraméterrel lett átadva.

$services = Get-Service
Format-Table -InputObject $services -Property Name, DependentServices

Vagy beágyazhatjuk a parancsot az InputObject paraméterbe.

Format-Table -InputObject (Get-Service) -Property Name, DependentServices

Van azonban egy fontos különbség. Ha több objektumot csövez egy parancsba, a PowerShell egyenként küldi el az objektumokat a parancsnak. Parancsparaméter használatakor az objektumok egyetlen tömbobjektumként lesznek elküldve. Ez a kisebb különbség jelentős következményekkel jár.

Folyamat végrehajtásakor a PowerShell automatikusan felsorol minden olyan típust, amely megvalósítja az interfészt vagy annak IEnumerable általános megfelelőjét. Az enumerált elemeket a rendszer egyenként küldi el a folyamaton keresztül. A PowerShell a System.Data.DataTable típusokat is számba adja a Rows tulajdonságon keresztül.

Az automatikus számbavétel alól néhány kivétel van.

  • Meg kell hívnia a kivonattáblák metódusát, az GetEnumerator() interfészt vagy annak IDictionary általános megfelelőjét megvalósító típusokat, valamint a System.Xml.XmlNode típusokat .
  • A System.String osztály implementálja IEnumerable, de a PowerShell nem számba veszi a sztringobjektumokat.

Az alábbi példákban egy tömböt és egy kivonatolót a rendszer a Measure-Object parancsmagba csövez, hogy megszámolja a folyamattól kapott objektumok számát. A tömbnek több tagja van, a kivonatolónak pedig több kulcs-érték párja van. Egyszerre csak a tömb van számba írva.

@(1,2,3) | Measure-Object
Count    : 3
Average  :
Sum      :
Maximum  :
Minimum  :
Property :
@{"One"=1;"Two"=2} | Measure-Object
Count    : 1
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

Hasonlóképpen, ha több folyamatobjektumot csövez a Get-Process parancsmagból a parancsmagba, a Get-Member PowerShell minden egyes folyamatobjektumot egyenként küld a parancsmagnak Get-Member. Get-Member Megjeleníti a folyamatobjektumok .NET-osztályát (típusát), valamint azok tulajdonságait és metódusait.

Get-Process | Get-Member
TypeName: System.Diagnostics.Process

Name      MemberType     Definition
----      ----------     ----------
Handles   AliasProperty  Handles = Handlecount
Name      AliasProperty  Name = ProcessName
NPM       AliasProperty  NPM = NonpagedSystemMemorySize
...

Feljegyzés

Get-Member kiküszöböli az ismétlődéseket, így ha az objektumok mind azonos típusúak, csak egy objektumtípust jelenít meg.

Ha azonban az InputObject paramétert Get-Memberhasználja, akkor Get-Member a System.Diagnostics.Process objektumokat egyetlen egységként kapja meg. Megjeleníti az objektumok tömbjének tulajdonságait. (Jegyezze fel a system.object típus neve után a tömbszimbólumot ([]).)

Például:

Get-Member -InputObject (Get-Process)
TypeName: System.Object[]

Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
Address            Method        System.Object& Address(Int32 )
Clone              Method        System.Object Clone()
...

Előfordulhat, hogy ez az eredmény nem a kívánt eredmény. De miután megértette, használhatja. Például minden tömbobjektum rendelkezik Count tulajdonságmal. Ezzel megszámolhatja a számítógépen futó folyamatok számát.

Például:

(Get-Process).count

Fontos megjegyezni, hogy a folyamaton keresztül küldött objektumok egyenként lesznek kézbesítve.

Natív parancsok használata a folyamatban

A PowerShell lehetővé teszi natív külső parancsok hozzáadását a folyamatba. Fontos azonban megjegyezni, hogy a PowerShell folyamata objektumorientált, és nem támogatja a nyers bájtadatokat.

A nyers bájtadatokat kiíró natív program kimenetének pipálása vagy átirányítása .NET-sztringekké alakítja a kimenetet. Ez az átalakítás a nyers adatkimenet sérülését okozhatja.

A PowerShell 7.4 azonban hozzáadta azt a kísérleti funkciót, amely megőrzi a PSNativeCommandPreserveBytePipe bájtfolyam adatait, amikor egy natív parancs stdout streamjét átirányítja egy fájlba, vagy amikor bájtfolyam-adatokat szór egy natív parancs stdin streamjére.

A natív paranccsal curl például letöltheti a bináris fájlokat, és átirányítással mentheti a lemezre.

$uri = 'https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz'

# native command redirected to a file
curl -s -L $uri > powershell.tar.gz

A byte-stream adatokat egy másik natív parancs stdin streamjére is átirányíthatja. Az alábbi példa egy tömörített TAR-fájlt tölt le a használatával curl. A letöltött fájladatok a parancsba kerülnek az tar archívum tartalmának kinyeréséhez.

# native command output piped to a native command
curl -s -L $uri | tar -xzvf - -C .

A PowerShell-parancsok bájtfolyam kimenetét a natív parancs bemenetére is átirányíthatja. Az alábbi példák ugyanazt a TAR-fájlt töltik Invoke-WebRequest le, mint az előző példában.

# byte stream piped to a native command
(Invoke-WebRequest $uri).Content | tar -xzvf - -C .

# bytes piped to a native command (all at once as byte[])
,(Invoke-WebRequest $uri).Content | tar -xzvf - -C .

Ez a funkció nem támogatja a bájtstreamelési adatokat, amikor stderr-kimenetet irányít át stdoutra. Az stderr és az stdout streamek egyesítésekor a rendszer sztringadatokként kezeli az egyesített streameket.

Folyamathibák kivizsgálása

Ha a PowerShell nem tudja társítani a vezetékes objektumokat a fogadó parancsmag egyik paraméterével, a parancs meghiúsul.

Az alábbi példában megpróbálunk áthelyezni egy beállításjegyzék-bejegyzést az egyik beállításkulcsból a másikba. A Get-Item parancsmag megkapja a cél elérési útját, amely ezután a Move-ItemProperty parancsmaghoz lesz csövezve. A Move-ItemProperty parancs megadja az áthelyezendő beállításjegyzék-bejegyzés aktuális elérési útját és nevét.

Get-Item -Path HKLM:\Software\MyCompany\sales |
Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product

A parancs sikertelen, és a PowerShell a következő hibaüzenetet jeleníti meg:

Move-ItemProperty : The input object can't be bound to any parameters for
the command either because the command doesn't take pipeline input or the
input and its properties do not match any of the parameters that take
pipeline input.
At line:1 char:23
+ $a | Move-ItemProperty <<<<  -Path HKLM:\Software\MyCompany\design -Name p

A vizsgálathoz használja a Trace-Command parancsmagot a PowerShell paraméterkötési összetevőjének nyomon követéséhez. Az alábbi példa a paraméterkötést követi nyomon a folyamat végrehajtása közben. A PSHost paraméter megjeleníti a nyomkövetési eredményeket a konzolon, és a FilePath paraméter elküldi a nyomkövetési eredményeket a debug.txt fájlnak későbbi hivatkozás céljából.

Trace-Command -Name ParameterBinding -PSHost -FilePath debug.txt -Expression {
  Get-Item -Path HKLM:\Software\MyCompany\sales |
    Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product
}

A nyomkövetés eredményei hosszadalmasak, de megjelenítik a parancsmaghoz Get-Item kötött értékeket, majd a parancsmaghoz Move-ItemProperty kötött elnevezett értékeket.

...
BIND NAMED cmd line args [`Move-ItemProperty`]
BIND arg [HKLM:\Software\MyCompany\design] to parameter [Path]
...
BIND arg [product] to parameter [Name]
...
BIND POSITIONAL cmd line args [`Move-ItemProperty`]
...

Végül azt mutatja, hogy a sikertelen célparaméter elérési útjának kötésére Move-ItemProperty tett kísérlet.

...
BIND PIPELINE object to parameters: [`Move-ItemProperty`]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values
Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
...

Get-Help A parancsmaggal megtekintheti a Cél paraméter attribútumait.

Get-Help Move-ItemProperty -Parameter Destination

-Destination <String>
    Specifies the path to the destination location.

    Required?                    true
    Position?                    1
    Default value                None
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

Az eredmények azt mutatják, hogy a Cél csak "tulajdonságnév alapján" veszi fel a folyamat bemenetét. Ezért a vezetékes objektumnak rendelkeznie kell egy Destination (Cél) nevű tulajdonságmal.

Az objektum Get-Itemtulajdonságainak megtekintésére használhatóGet-Member.

Get-Item -Path HKLM:\Software\MyCompany\sales | Get-Member

A kimenet azt mutatja, hogy az elem egy Microsoft.Win32.RegistryKey objektum, amely nem rendelkezik Cél tulajdonságmal. Ez megmagyarázza, hogy miért nem sikerült a parancs.

Az Elérési út paraméter név vagy érték alapján fogadja el a folyamat bemenetét.

Get-Help Move-ItemProperty -Parameter Path

-Path <String[]>
    Specifies the path to the current location of the property. Wildcard
    characters are permitted.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  true

A parancs kijavításához meg kell adnunk a Move-ItemProperty parancsmag célhelyét, és Get-Item le kell kérnünk az áthelyezni kívánt elem elérési útját .

Például:

Get-Item -Path HKLM:\Software\MyCompany\design |
Move-ItemProperty -Destination HKLM:\Software\MyCompany\sales -Name product

Belső vonal folytatása

Ahogy már említettem, a folyamat a folyamatkezelők (|) által csatlakoztatott parancsok sorozata, amelyek általában egyetlen sorban vannak megírva. Az olvashatóság érdekében azonban a PowerShell lehetővé teszi a folyamat több sorra való felosztását. Ha egy csőművelet az utolsó jogkivonat a sorban, a PowerShell-elemző a következő sort az aktuális parancshoz illeszti a folyamat építésének folytatásához.

Például a következő egysoros folyamat:

Command-1 | Command-2 | Command-3

a következő módon írható:

Command-1 |
    Command-2 |
    Command-3

A következő sorok kezdő szóközei nem jelentősek. A behúzás növeli az olvashatóságot.

A PowerShell 7 támogatja a folyamatok folytatását a vonal elején lévő folyamat karakterrel. Az alábbi példák bemutatják, hogyan használhatja ezt az új funkciót.

# Wrapping with a pipe at the beginning of a line (no backtick required)
Get-Process | Where-Object CPU | Where-Object Path
    | Get-Item | Where-Object FullName -match "AppData"
    | Sort-Object FullName -Unique

# Wrapping with a pipe on a line by itself
Get-Process | Where-Object CPU | Where-Object Path
    |
    Get-Item | Where-Object FullName -match "AppData"
    |
    Sort-Object FullName -Unique

Fontos

Ha interaktívan dolgozik a rendszerhéjban, a kódot csak a sor elején lévő folyamatokkal illessze be, amikor a Ctrl V billentyűkombinációt+használja a beillesztéshez. A jobb gombbal kattintva a beillesztési műveletek egyenként szúrják be a sorokat. Mivel a sor nem végződik folyamat karakterrel, a PowerShell befejezettnek tekinti a bemenetet, és a megadott módon hajtja végre a sort.

Lásd még