Ograniczenia transkrypcji programu PowerShell
Mieszanie Write-Host
danych wyjściowych z obiektami wyjściowymi, ciągami i transkrypcją programu PowerShell jest skomplikowane. Istnieje subtelna interakcja między skryptem a sposobem działania transkrypcji z potokami programu PowerShell, które mogą mieć nieoczekiwane wyniki.
Podczas emitowania obiektów ze skryptu formatowanie tych obiektów jest obsługiwane przez Out-Default
element .
Jednak formatowanie może wystąpić po zakończeniu działania skryptu i zatrzymaniu transkrypcji. Oznacza to, że dane wyjściowe nie są transkrypowane. Ciągi są obsługiwane inaczej. Czasami dane wyjściowe ciągu są przekazywane przez formatowanie, ale nie zawsze. Write-Host
tworzy natychmiastowy zapis w procesie hosta. Write-Object
jest wysyłany za pośrednictwem systemu formatowania. Połączenie danych wyjściowych złożonych obiektów z zapisami na hoście utrudnia przewidywanie, co jest rejestrowane w transkrypcji.
Scenariusz 1 — dane wyjściowe obiektu ustrukturyzowanego na końcu wszystkich innych operacji
Rozważmy następujący skrypt i jego dane wyjściowe:
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
Dane wyjściowe w konsoli zawierają oczekiwane dane wyjściowe, ale nie w oczekiwanej kolejności.
Write-Host 4
jest widoczny przed Get-Location
, ponieważ Write-Host
jest zoptymalizowany pod kątem zapisywania bezpośrednio na hoście. Istnieje kod w transkrypcji, który kopiuje dane wyjściowe do pliku transkrypcji i konsoli. Następnie mamy regularne dane wyjściowe Get-Location
i Write-Output 5
wysyłane jako dane wyjściowe skryptu.
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
**********************
Ponieważ transkrypcja jest wyłączona przed zakończeniem działania skryptu, nie jest renderowana w transkrypcji. Obiekty zostały wysłane do następnego konsumenta w potoku. W tym przypadku jest to Out-Default
polecenie , które program PowerShell wstawił automatycznie. Aby jeszcze bardziej skomplikować kwestie, dane wyjściowe ciągów są również zoptymalizowane w systemie formatowania. Pierwszy Write-Output 2
jest emitowany i przechwytywany przez transkrypcję. Jednak wstawienie Get-Location
obiektu powoduje wypchnięcie jego danych wyjściowych do stosu elementów, które wymagają rzeczywistego formatowania, co ustawia bit stanu dla pozostałych obiektów, które również mogą wymagać formatowania. Dlatego drugi Write-Output 5
nie zostanie dodany do transkrypcji.
Scenariusz 2 — przenoszenie emisji obiektu na początek
Rozważmy następujący skrypt i jego dane wyjściowe:
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
Widzimy, że Write-Host
polecenia są wykonywane przed wszystkimi elementami, a następnie zaczynają wychodzić obiekty. Ciąg Write-Output
wymusza renderowanie obiektu na ekranie, ale zwróć uwagę, że transkrypcja zawiera tylko dane wyjściowe .Write-Host
Dzieje się tak, ponieważ te obiekty ciągów są przesyłane potokiem do Out-Default
formatowania po wyłączeniu transkrypcji skryptu.
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
**********************
Scenariusz 3 — obiekt emitowany na końcu skryptu
W tym scenariuszu dane wyjściowe obiektu złożonego są na końcu skryptu.
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
Dane wyjściowe ciągu z obu Write-Host
elementów i Write-Object
sprawiają, że są wprowadzane do transkrypcji. Jednak dane wyjściowe z Get-Location
wystąpią po zatrzymaniu transkrypcji.
**********************
PowerShell transcript start
Start time: 20220606100342
**********************
Transcript started, output file is scenario3.log
1
2
4
5
**********************
PowerShell transcript end
End time: 20220606100342
**********************
Sposób zapewnienia pełnej transkrypcji
Ten przykład jest nieznaczną odmianą oryginalnego scenariusza, ale teraz wszystko jest rejestrowane w transkrypcji. Oryginalny kod jest opakowany w blok skryptu, a formater jawnie wywoływany za pośrednictwem metody 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
Zwróć uwagę, że ostatnie Write-Host
wywołanie jest nadal poza kolejnością, co wynika z optymalizacji, Write-Host
która nie przechodzi do strumienia wyjściowego.
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
**********************
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla