Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La combinazione Write-Host
dell'output con gli oggetti di output, le stringhe e la trascrizione di PowerShell è complicata. Esiste un'interazione sottile tra lo script e il funzionamento della trascrizione con le pipeline di PowerShell che possono avere risultati imprevisti.
Quando si emettono oggetti dallo script, la formattazione di tali oggetti viene gestita da Out-Default
.
Tuttavia, la formattazione può verificarsi dopo il completamento dello script e la trascrizione è stata arrestata. Ciò significa che l'output non viene trascritto. Le stringhe vengono gestite in modo diverso. A volte l'output stringa viene passato attraverso la formattazione, ma non sempre.
Write-Host
esegue una scrittura immediata nel processo host.
Write-Output
viene inviato tramite il sistema di formattazione. La combinazione dell'output di oggetti complessi con operazioni di scrittura verso l'host rende difficile prevedere cosa venga registrato nella trascrizione.
Scenario 1 - Output di un oggetto strutturato dopo tutte le altre operazioni
Si consideri lo script seguente e il relativo output:
PS> Get-Content scenario1.ps1
Start-Transcript scenario1.log -UseMinimalHeader
Write-Host '1'
Write-Output '2'
Get-Location
Write-Host '4'
Write-Output '5'
Stop-Transcript
PS> ./scenario1.ps1
Transcript started, output file is scenario1.log
1
2
4
Path
----
/Users/user1/src/projects/transcript
5
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario1.log
L'output nella console mostra l'output previsto, ma non nell'ordine che ti aspetti.
Write-Host 4
è visibile prima Get-Location
perché Write-Host
è ottimizzato per scrivere direttamente nell'host. Nella trascrizione è presente codice che copia l'output nel file di trascrizione e nella console. Avremo quindi l'output regolare di Get-Location
e Write-Output 5
fornito come output dello script.
PS> Get-Content scenario1.log
**********************
PowerShell transcript start
Start time: 20191106114858
**********************
Transcript started, output file is s2
1
2
4
**********************
PowerShell transcript end
End time: 20191106114858
**********************
Poiché la trascrizione viene disattivata prima che il script termini, non appare nella trascrizione. Gli oggetti sono stati consegnati al consumatore successivo nella pipeline. In questo caso, è Out-Default
, che PowerShell ha inserito automaticamente. Per complicare ulteriormente le cose, anche l'output delle stringhe viene ottimizzato nel sistema di formattazione. Il primo Write-Output 2
viene emesso e acquisito dalla trascrizione. Tuttavia, l'inserimento dell'oggetto determina il push dell'output Get-Location
nello stack di elementi che richiedono una formattazione effettiva, che imposta un bit di stato per gli oggetti rimanenti che potrebbero anche richiedere la formattazione. Ecco perché il secondo Write-Output 5
non viene aggiunto alla trascrizione.
Scenario 2 - Spostare l'emissione dell'oggetto all'inizio
Si consideri lo script seguente e il relativo output:
PS> Get-Content scenario2.ps1
Start-Transcript scenario2.log -UseMinimalHeader
Get-Location
Write-Host '1'
Write-Output '2'
Get-Location
Write-Host '4'
Write-Output '5'
Stop-Transcript
PS> ./scenario2.ps1
Transcript started, output file is scenario2.log
1
4
Path
----
/Users/user1/src/projects/transcript
2
5
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario2.log
È possibile notare che i Write-Host
comandi si verificano prima di tutto il resto e quindi gli oggetti iniziano a emergere. L'esecuzione di Write-Output
su una stringa forza il rendering dell'oggetto sullo schermo, ma si noti che nella trascrizione è presente solo l'output di Write-Host
. Ciò è dovuto al fatto che tali oggetti stringa vengono inviati tramite pipe a Out-Default
per la formattazione dopo che lo script ha disattivato la trascrizione.
PS> Get-Content scenario2.log
**********************
PowerShell transcript start
Start time: 20220606094609
**********************
Transcript started, output file is s3
1
4
**********************
PowerShell transcript end
End time: 20220606094609
**********************
Scenario 3 - Oggetto generato alla fine dello script
Per questo scenario, l'output dell'oggetto complesso si trova alla fine dello script.
PS> Get-Content scenario3.ps1
Start-Transcript scenario3.log -UseMinimalHeader
Write-Host '1'
Write-Output '2'
Write-Host '4'
Write-Output '5'
Get-Location
Stop-Transcript
PS> ./scenario3.ps1
Transcript started, output file is scenario3.log
1
2
4
5
Path
----
/Users/user1/src/projects/transcript
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario3.log
L'output della stringa di entrambi Write-Host
e Write-Output
è incluso nella trascrizione. Tuttavia, l'output di Get-Location
avviene dopo che la trascrizione si è fermata.
**********************
PowerShell transcript start
Start time: 20220606100342
**********************
Transcript started, output file is scenario3.log
1
2
4
5
**********************
PowerShell transcript end
End time: 20220606100342
**********************
Un modo per garantire la trascrizione completa
Questo esempio è una leggera variazione nello scenario originale, ma ora tutto viene registrato nella trascrizione. Il codice originale è racchiuso in un blocco di script e il formattatore è richiamato esplicitamente tramite Out-Default
.
PS> Get-Content scenario4.ps1
Start-Transcript scenario4.log -UseMinimalHeader
. {
Write-Host '1'
Write-Output '2'
Get-Location
Write-Host '4'
Write-Output '5'
} | Out-Default
Stop-Transcript
PS> ./scenario4.ps1
Transcript started, output file is scenario4.log
1
2
4
Path
----
/Users/user1/src/projects/transcript
5
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario4.log
Si noti che l'ultima chiamata Write-Host
è ancora fuori sequenza, a causa dell'ottimizzazione in Write-Host
che non viene inclusa nel flusso di output.
PS> Get-Content scenario4.log
**********************
PowerShell transcript start
Start time: 20220606101038
**********************
Transcript started, output file is s5
1
2
4
Path
----
/Users/user1/src/projects/transcript
5
**********************
PowerShell transcript end
End time: 20220606101038
**********************