Pipeline (|) în PowerShell

Primii pași Windows PowerShell 1.0

Operatorul | trimite obiectele unei comenzi, unul câte unul, comenzii următoare; $_ este obiectul curent, iar && și || înlănțuie comenzi.

Sintaxă
<comandă1> | <comandă2> | <comandă3>
<pipeline1> && <pipeline2>
<pipeline1> || <pipeline2>

Ce face Pipeline (|)

Operatorul | (pipeline) leagă comenzi: ce produce comanda din stânga ajunge la intrarea comenzii din dreapta. Diferența față de CMD sau Bash este că prin pipeline circulă obiecte .NET, nu text. Get-ChildItem trimite obiecte fișier cu proprietăți (Name, Length, LastWriteTime), iar Where-Object sau Sort-Object lucrează direct cu ele, fără să tai coloane de text.

Obiectele trec pe rând. În blocurile de script ale lui ForEach-Object și Where-Object, obiectul curent este în variabila automată $_, care are și numele lung $PSItem (din Windows PowerShell 3.0). Abia comanda de la capătul pipeline-ului transformă obiectele în text pentru ecran.

Din PowerShell 7.0 există și operatorii de înlănțuire && și ||, ca în Bash: a && b rulează b doar dacă a a reușit, iar a || b rulează b doar dacă a a eșuat. Reușita se judecă după $? (și după $LASTEXITCODE pentru programe externe), nu după valoarea întoarsă. În Windows PowerShell 5.1 acești operatori nu există.

Parametri

Parametru Descriere
| Trimite ieșirea comenzii din stânga către comanda din dreapta, obiect cu obiect.
$_ / $PSItem Obiectul curent din pipeline, în blocurile de script ({ $_.Name }).
&& Rulează pipeline-ul din dreapta doar dacă cel din stânga a reușit (PowerShell 7.0+).
|| Rulează pipeline-ul din dreapta doar dacă cel din stânga a eșuat (PowerShell 7.0+).

Exemple

Exemplul 1: Filtrezi și alegi coloane fără să prelucrezi text

Fișierele mai mari de 1 MB din folderul de facturi, cu numele și dimensiunea în octeți. Length este un număr, deci comparația cu 1MB e numerică.

Get-ChildItem C:\Proiecte\facturi -File |
    Where-Object Length -gt 1MB |
    Select-Object Name, Length

Ieșire în terminal

Name             Length
----             ------
factura-ana.pdf 2457600
raport-cluj.pdf 1310720

Exemplul 2: Obiectul curent: $_ și $PSItem

Cele două variabile sunt identice; $PSItem se citește mai ușor în scripturi.

'Ana', 'Mihai' | ForEach-Object { "Salut, $PSItem!" }
1..3 | ForEach-Object { $_ * 10 }

Ieșire în terminal

Salut, Ana!
Salut, Mihai!
10
20
30

Exemplul 3: Un mesaj doar când comanda eșuează (||)

Get-Item eșuează pentru că fișierul nu există, deci se rulează și partea din dreapta lui ||.

Get-Item C:\Proiecte\lipsa.txt || Write-Output 'Fișierul lipsește'

Ieșire în terminal

Get-Item: Cannot find path 'C:\Proiecte\lipsa.txt' because it does not exist.
Fișierul lipsește

Greșeli frecvente

  • Să tratezi ieșirea ca text, cu Select-String sau tăieri de coloane, când poți filtra direct pe proprietăți: Where-Object Length -gt 1MB.
  • Să pui Format-Table la mijlocul pipeline-ului: după el nu mai ai obiectele originale. Formatarea se pune ultima.
  • Să folosești && ca „și dacă rezultatul e adevărat”: Test-Path x && ... rulează partea a doua și când Test-Path întoarce False, pentru că, din punctul de vedere al lui PowerShell, comanda a reușit. Pentru condiții folosește if.
  • Să scrii && sau || într-un script care trebuie să ruleze și în Windows PowerShell 5.1: acolo e eroare de sintaxă.

Comenzi înrudite

  • Get-Member: Arată tipul obiectelor dintr-un pipeline și ce proprietăți și metode au, ca să știi ce poți selecta, filtra sau apela.
  • Where-Object: Filtrează obiectele din pipeline și le lasă să treacă doar pe cele care îndeplinesc o condiție.
  • ForEach-Object: Rulează un bloc de cod pentru fiecare obiect din pipeline; din PowerShell 7.0 poate rula blocurile în paralel cu -Parallel.
  • Select-Object: Alege doar anumite proprietăți ale obiectelor, adaugă proprietăți calculate sau păstrează primele, ultimele ori unicele elemente.
  • if / elseif / else: if rulează un bloc de cod doar când condiția e adevărată; elseif și else tratează celelalte cazuri, iar ?: (din PowerShell 7.0) e forma scurtă.