Omezení přepisů PowerShellu
Kombinování Write-Host
výstupu s výstupními objekty, řetězci a přepisem PowerShellu je složité. Mezi skriptem a fungováním přepisu s kanály PowerShellu je malá interakce, která může mít neočekávané výsledky.
Při generování objektů ze skriptu formátování těchto objektů je zpracována Out-Default
.
Formátování ale může nastat po dokončení skriptu a zastavení přepisu. To znamená, že výstup se nepřepíše. Řetězce se zpracovávají odlišně. Výstup řetězce se někdy předává prostřednictvím formátování, ale ne vždy. Write-Host
vytvoří okamžitý zápis do hostitelského procesu. Write-Object
se odesílá prostřednictvím systému formátování. Kombinací výstupu složitých objektů s zápisy do hostitele je obtížné předpovědět, co se zaprotokoluje v přepisu.
Scénář 1 – výstup strukturovaného objektu na konci všech ostatních operací
Zvažte následující skript a jeho výstup:
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
Výstup konzoly zobrazí očekávaný výstup, ale ne v pořadí, v jakém ho očekáváte.
Write-Host 4
je viditelný dříve Get-Location
, protože Write-Host
je optimalizovaný pro zápis přímo do hostitele. V přepisu je kód, který zkopíruje výstup do souboru přepisu a konzoly. Pak máme běžný výstup Get-Location
a Write-Output 5
odešleme ho jako výstup skriptu.
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
**********************
Vzhledem k tomu, že se přepis vypne před ukončením skriptu, nevykreslí se v přepisu. Objekty byly odeslány dalšímu příjemci v kanálu. V tomto případě se Out-Default
jedná o powershell, který se automaticky vloží. Aby se věci dále komplikovaly, výstup řetězců je také optimalizovaný v systému formátování. Write-Output 2
První se vygeneruje a zachytí přepisem. Vložení objektu Get-Location
ale způsobí, že se jeho výstup vloží do zásobníku věcí, které potřebují skutečné formátování, což nastaví určitý stav pro všechny zbývající objekty, které můžou také potřebovat formátování. To je důvod, proč se druhý Write-Output 5
nepřidá do přepisu.
Scénář 2 – Přesunutí emisí objektů na začátek
Zvažte následující skript a jeho výstup:
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
Vidíme, že Write-Host
příkazy probíhají před čímkoli a pak se objekty začnou vycházet. Řetězec Write-Output
vynutí vykreslení objektu na obrazovku, ale všimněte si, že přepis obsahuje pouze výstup .Write-Host
Je to proto, že tyto objekty řetězců se předávají Out-Default
pro formátování po vypnutí přepisu skriptu.
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
**********************
Scénář 3 – Objekt vygenerovaný na konci skriptu
V tomto scénáři je výstup komplexního objektu na konci skriptu.
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
Výstup řetězce z obou Write-Host
a Write-Object
převede ho do přepisu. K výstupu Get-Location
dojde však po zastavení přepisu.
**********************
PowerShell transcript start
Start time: 20220606100342
**********************
Transcript started, output file is scenario3.log
1
2
4
5
**********************
PowerShell transcript end
End time: 20220606100342
**********************
Způsob, jak zajistit úplný přepis
Tento příklad je mírným rozdílem v původním scénáři, ale teď se všechno zaprotokoluje do přepisu. Původní kód je zabalen do bloku skriptu a formátovací modul explicitně vyvolá pomocí 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
Všimněte si, že poslední Write-Host
volání je stále mimo pořadí, je to kvůli optimalizaci, Write-Host
která nepřechází do výstupního datového proudu.
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
**********************
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro