2013-06-26 10 views
8

Capisco che le tubazioni di PowerShell funzionano prendendo l'output di un cmdlet e passandolo a un altro cmdlet come input. Ma come si fa a fare questo?Come funziona il concetto di pipeline di PowerShell?

Il primo cmdlet termina e quindi passa tutte le variabili di output contemporaneamente, che vengono quindi elaborate dal cmdlet successivo?

Oppure ogni output dal primo cmdlet viene preso uno alla volta e quindi eseguito attraverso tutti i cmdlet del piping rimanenti?

risposta

10

Si può vedere come ordine gasdotto funziona con un po 'di semplice script:

function a {begin {Write-Host 'begin a'} process {Write-Host "process a: $_"; $_} end {Write-Host 'end a'}} 
function b {begin {Write-Host 'begin b'} process {Write-Host "process b: $_"; $_} end {Write-Host 'end b'}} 
function c { Write-Host 'c' } 

1..3 | a | b | c 

Uscite:

begin a 
begin b 
process a: 1 
process b: 1 
process a: 2 
process b: 2 
process a: 3 
process b: 3 
end a 
end b 
c 
5

Il tubo Powershell funziona in modo asincrono. Significa che l'output del primo cmdlet è disponibile per il secondo cmdlet immediatamente un oggetto alla volta (anche se il primo non ha terminato l'esecuzione).

Per esempio, se si esegue la riga di seguito:

dir -recurse| out-file C:\a.txt 

e quindi fermare l'esecuzione premendo Ctrl + C si vedrà parte di directory viene scritto nel file di testo.

Un esempio migliore è il seguente codice: (che è davvero utile per eliminare tutti i file tmp sul disco C :)

get-childitem c:\ -include *.tmp -recurse | foreach ($_) {remove-item $_.fullname} 

Ogni volta che $ _ nel secondo cmdlet ottiene il valore di un (singolo file)

1

Entrambe le risposte danno quindi alcune informazioni utili sul pipelining. Tuttavia, c'è ancora molto da dire.

In primo luogo, per indirizzare direttamente la tua domanda, hai posto due possibili modi in cui la pipeline potrebbe funzionare. E hanno entrambi ragione ... a seconda dei cmdlet su entrambi i lati del tubo! Tuttavia, il modo in cui la pipeline deve essere è più vicino alla seconda nozione: gli oggetti vengono elaborati uno alla volta. (Anche se non è garantito che un oggetto vada avanti prima che venga avviato il prossimo perché ogni componente nella pipeline è asincrono, come menzionato da S Nash.)

Quindi, cosa intendo per "dipende dal tuo cmdlet "? Se si parla di cmdlet forniti da Microsoft, probabilmente funzioneranno tutti come ci si aspetterebbe, passando ogni oggetto attraverso la pipeline nel modo più efficiente possibile. Ma se parli di cmdlet che scrivi, dipende da come li scrivi: è altrettanto facile scrivere cmdlet che non riescono a fare il pipeline appropriato come quelli che hanno successo!

Ci sono due principali tipi di problemi:

  • generano tutta l'uscita prima di emettere qualsiasi nella tubazione, o
  • recuperare tutto input pipeline prima di elaborare qualsiasi.

Ciò che si vuole sforzare, naturalmente, è elaborare ogni input non appena viene ricevuto ed emettere l'output non appena viene determinato.Per esempi dettagliati di tutti questi vedi il mio articolo, Ins and Outs of the PowerShell Pipeline, appena pubblicato su Simple-Talk.com.