Uwaga: Poniższe informacje dotyczą programu Windows PowerShell .
Zobacz następną sekcję dotyczącą wieloplatformowej wersji programu PowerShell Core (v6 +) .
Na PSv5.1 lub nowszym , gdzie >i >>są efektywnymi aliasami Out-File, możesz ustawić domyślne kodowanie dla >/ >>/ Out-Filepoprzez $PSDefaultParameterValueszmienną preferencji :
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
Na PSv5.0 lub poniżej , to nie można zmienić kodowanie >/>> , ale na PSv3 lub wyższy , powyższa technika czyni pracę dla jawnych wywołańOut-File .
( $PSDefaultParameterValuesZmienna preferencji została wprowadzona w PSv3.0).
Na PSv3.0 lub wyższy , jeśli chcesz ustawić domyślne kodowanie dla wszystkich apletów poleceń, które obsługują
to -Encodingparametr (co obejmuje w PSv5.1 + >i >>), przeznaczenie:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
Jeśli umieścisz to polecenie w swoich poleceniach$PROFILE cmdlet, takich jak Out-FileiSet-Content będą domyślnie używać kodowania UTF-8, ale pamiętaj, że powoduje to ustawienie globalne sesji, które będzie miało wpływ na wszystkie polecenia / skrypty, które nie określają jawnie kodowania.
Podobnie, pamiętaj, aby w swoich skryptach lub modułach uwzględnić takie polecenia, które chcesz, aby zachowywały się w ten sam sposób , aby rzeczywiście zachowywały się tak samo, nawet jeśli są uruchamiane przez innego użytkownika lub inną maszynę.
Uwaga : PowerShell, począwszy od wersji 5.1, niezmiennie tworzy pliki UTF-8 _ z (pseudo) BOM_ , co jest zwyczajowe tylko w świecie Windows - narzędzia oparte na Uniksie nie rozpoznają tego BOM (patrz poniżej); zobacz ten post, aby poznać obejścia, które powodują tworzenie plików UTF-8 bez BOM.
Dla podsumowania szalenie niespójne domyślnego kodowania znaków zachowanie całej wiele standardowych poleceń cmdlet Windows PowerShell , zobacz dolną część.
$OutputEncodingZmienna automatyczna jest niepowiązana i dotyczy tylko sposobu, w jaki PowerShell komunikuje się z programami zewnętrznymi (jakiego kodowania używa PowerShell podczas wysyłania do nich ciągów) - nie ma nic wspólnego z kodowaniem używanym przez operatory przekierowania danych wyjściowych i polecenia cmdlet programu PowerShell do zapisywania w plikach.
Czytanie opcjonalne: perspektywa międzyplatformowa: PowerShell Core :
PowerShell jest teraz wieloplatformowy , za pośrednictwem wersji PowerShell Core , której kodowanie - rozsądnie - jest domyślnie ustawione na UTF-8 bez BOM , zgodnie z platformami typu Unix.
Oznacza to, że pliki kodu źródłowego bez BOM przyjmowane są za UTF-8, a przy użyciu >/ Out-File/ Set-Contentdomyślnie BOM mniej UTF-8; jawne użycie utf8 -Encodingargumentu również tworzy kod UTF-8 bez BOM , ale możesz zdecydować się na tworzenie plików z pseudo-BOM z utf8bomwartością.
Jeśli tworzysz skrypty PowerShell za pomocą edytora na platformie uniksopodobnej, a obecnie nawet w systemie Windows z edytorami wieloplatformowymi, takimi jak Visual Studio Code i Sublime Text, wynikowy *.ps1plik zazwyczaj nie będzie miał pseudo-BOM UTF-8:
- Działa to dobrze w programie PowerShell Core .
- Może się zepsuć w programie Windows PowerShell , jeśli plik zawiera znaki spoza zestawu ASCII; jeśli musisz używać znaków spoza zestawu ASCII w swoich skryptach, zapisz je jako UTF-8 z BOM .
Bez BOM program Windows PowerShell (mis) interpretuje skrypt jako zakodowany na starszej stronie kodowej „ANSI” (określonej przez ustawienia regionalne systemu dla aplikacji poprzedzających Unicode, np. Windows-1252 w systemach amerykańsko-angielskich).
Odwrotnie, pliki, które zrobienia mieć UTF-8 pseudo-BOM może być problematyczne na uniksowych platformach, ponieważ przyczyna narzędzi uniksowych takich jak cat, sedi awk- a nawet niektórzy redaktorzy takie jak gedit- aby zdać pseudo-LM dzięki , czyli traktować to jako dane .
- Nie zawsze może to stanowić problem, ale na pewno może tak być, na przykład przy próbie wczytania pliku do łańcucha
bashz, powiedzmy, text=$(cat file)lub text=$(<file)- zmienna wynikowa będzie zawierała pseudo-BOM jako pierwsze 3 bajty.
Niespójne domyślne zachowanie kodowania w programie Windows PowerShell :
Niestety, domyślne kodowanie znaków używane w programie Windows PowerShell jest bardzo niespójne; wieloplatformowa edycja PowerShell Core , jak omówiono w poprzedniej sekcji, chwalebnie położyła to i zakończyła.
Uwaga:
Poniższe aspiracje nie obejmują wszystkich standardowych poleceń cmdlet.
Wyszukiwanie w Google nazw poleceń cmdlet w celu znalezienia ich tematów pomocy teraz pokazuje domyślnie wersję PowerShell Core tematów; użyj listy rozwijanej wersji nad listą tematów po lewej stronie, aby przełączyć się na wersję programu Windows PowerShell .
W chwili pisania tego tekstu dokumentacja często błędnie twierdzi, że ASCII jest domyślnym kodowaniem w programie Windows PowerShell - zobacz ten problem z dokumentacją GitHub .
Polecenia cmdlet, które piszą :
Out-Filei >/ >>utwórz „Unicode” - UTF-16LE - pliki domyślnie - w których każdy znak z zakresu ASCII (także) jest reprezentowany przez 2 bajty - co znacznie różni się od Set-Content/ Add-Content(patrz następny punkt); New-ModuleManifesta Export-CliXmltakże tworzyć pliki UTF-16LE.
Set-Content(a Add-Contentjeśli plik jeszcze nie istnieje / jest pusty) używa kodowania ANSI (kodowanie określone przez starszą stronę kodową ANSI aktywnego ustawienia regionalnego, którą wywołuje program PowerShell Default).
Export-Csvrzeczywiście tworzy pliki ASCII, zgodnie z dokumentacją, ale zobacz uwagi -Appendponiżej.
Export-PSSession domyślnie tworzy pliki UTF-8 z BOM.
New-Item -Type File -Value obecnie tworzy bez BOM (!) UTF-8.
W Send-MailMessagetemacie pomocy podano również, że kodowanie ASCII jest domyślne - osobiście nie zweryfikowałem tego twierdzenia.
Start-Transcript niezmiennie tworzy pliki UTF-8 z BOM, ale zobacz uwagi -Appendponiżej.
Ponownie polecenia dołączane do istniejącego pliku:
>>/ Out-File -AppendZrobić żadnej próby pasujące kodowanie pliku w istniejącej zawartości . Oznacza to, że ślepo stosują swoje domyślne kodowanie, chyba że poinstruowano inaczej -Encoding, co nie jest opcją z >>( z wyjątkiem pośrednio w PSv5.1 +, przez $PSDefaultParameterValues, jak pokazano powyżej). W skrócie: musisz znać kodowanie zawartości istniejącego pliku i dołączyć przy użyciu tego samego kodowania.
Add-Contentjest chwalebnym wyjątkiem: w przypadku braku wyraźnego -Encodingargumentu wykrywa istniejące kodowanie i automatycznie stosuje je do nowej treści. Dzięki, js2010 . Należy zauważyć, że w programie Windows PowerShell oznacza to, że jest to kodowanie ANSI, które jest stosowane, jeśli istniejąca zawartość nie ma BOM, podczas gdy w programie PowerShell Core jest to UTF-8.
Ta niespójność między Out-File -Append/ >>i Add-Content, która ma również wpływ na program PowerShell Core , została omówiona w tym problemie w usłudze GitHub .
Export-Csv -Append częściowo pasuje do istniejącego kodowania: ślepo dołącza UTF-8, jeśli kodowanie istniejącego pliku jest dowolne z ASCII / UTF-8 / ANSI, ale poprawnie pasuje do UTF-16LE i UTF-16BE.
Ujmując to inaczej: w przypadku braku BOM Export-Csv -Appendzakłada , że UTF-8 jest, podczas gdy Add-Contentzakłada ANSI.
Start-Transcript -Append częściowo pasuje do istniejącego kodowania: prawidłowo dopasowuje kodowanie z BOM , ale domyślnie stosuje potencjalnie stratne kodowanie ASCII w przypadku jego braku.
Polecenia cmdlet, które odczytują (to znaczy kodowanie używane w przypadku braku BOM ):
Get-Contenti Import-PowerShellDataFiledomyślnie ANSI ( Default), co jest zgodne z Set-Content.
ANSI jest również tym, co sam aparat PowerShell domyślnie przyjmuje, gdy odczytuje kod źródłowy z plików.
Natomiast Import-Csv, Import-CliXmli Select-Stringzakładamy, UTF-8 w przypadku braku BOM.