Примітка: Наступне стосується Windows PowerShell .
Див. Наступний розділ для крос-платформного видання PowerShell Core (v6 +) .
На PSv5.1 або новішій версії , де >
і >>
фактично є псевдонімами Out-File
, ви можете встановити кодування за замовчуванням для >
/ >>
/ Out-File
через $PSDefaultParameterValues
змінну налаштування :
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
На PSv5.0 або нижче , ви не можете змінити кодування >
/>>
, але, на PSv3 або вище , вище метод робить роботу явних дзвінківOut-File
.
( $PSDefaultParameterValues
Змінна переваги була введена в PSv3.0).
На PSv3.0 або вище , якщо ви хочете встановити за замовчуванням кодування для всіх командлетів , які підтримують
в -Encoding
параметр (який в PSv5.1 + включає в себе >
і >>
), використовуйте:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
Якщо ви розміщуєте цю команду у своїх$PROFILE
командлетах, таких як Out-File
іSet-Content
використовуватимуть кодування UTF-8 за замовчуванням, але зверніть увагу, що це робить це глобальне налаштування сеансу, яке впливатиме на всі команди / сценарії, які явно не вказують кодування.
Так само, не забудьте включити такі команди у свої сценарії або модулі, які ви хочете поводитись однаково , щоб вони справді поводились однаково, навіть коли їх запускає інший користувач або інша машина.
Увага : ** PowerShell, починаючи з версії 5.1, незмінно створює файли UTF-8 з (псевдо) специфікацією _ ** , що є звичним лише у світі Windows - утиліти на базі Unix не розпізнають цю специфікацію (див. Внизу); див. цю публікацію щодо обхідних шляхів, що створюють файли UTF-8 без спеціальних специфікацій.
Для резюме дико непослідовної поведінки кодування символів за замовчуванням в багатьох стандартних командлетів Windows PowerShell см нижню секцію.
Автоматична $OutputEncoding
змінна не пов’язана між собою і застосовується лише до того, як PowerShell взаємодіє із зовнішніми програмами (те, що кодування використовує PowerShell, коли надсилає їм рядки) - це не має нічого спільного з кодуванням, яке використовують оператори перенаправлення виводу та командлети PowerShell для збереження у файлах.
Необов’язкове читання: Перспектива між платформами: Ядро PowerShell :
PowerShell тепер є крос-платформенною завдяки своїй версії PowerShell Core , кодування якої - розумно - за замовчуванням не потребує специфікації UTF-8 , відповідно до Unix-подібних платформ.
Це означає , що вихідний код-файли без специфікації передбачається UTF-8, і з допомогою >
/ Out-File
/ по Set-Content
замовчуванням в специфікацію менш UTF-8; явне використання utf8
-Encoding
аргументу також створює без специфікації UTF-8, але ви можете створити файли з псевдо специфікацією зі utf8bom
значенням.
Якщо ви створюєте сценарії PowerShell за допомогою редактора на Unix-подібній платформі, а сьогодні навіть у Windows з крос-платформенними редакторами, такими як Visual Studio Code та Sublime Text, отриманий *.ps1
файл зазвичай не матиме псевдо-специфікації UTF-8:
- Це чудово працює на PowerShell Core .
- Це може зламатись у Windows PowerShell , якщо файл містить символи, що не є ASCII; якщо вам потрібно використовувати в сценаріях символи, що не є ASCII, збережіть їх як UTF-8 разом із специфікацією .
Без спеціальної специфікації Windows PowerShell (помилково) інтерпретує ваш сценарій як кодований у застарілій кодовій сторінці "ANSI" (визначається локальною системою для додатків до Unicode; наприклад, Windows-1252 в американсько-англійських системах).
З іншого боку , файли , які роблять мають UTF-8 псевдо-BOM може бути проблематичним , на Unix-подібних платформах, так як вони викликають Unix утиліт , таких як cat
, sed
і awk
- і навіть деякі редактори , такі як gedit
- щоб передати псевдо-BOM через , тобто розглядати це як дані .
- Це не завжди може бути проблемою, але однозначно може бути, наприклад, коли ви намагаєтесь прочитати файл у рядок
bash
, скажімо, text=$(cat file)
або text=$(<file)
- отримана змінна міститиме псевдо-специфікацію як перші 3 байти.
Невідповідна поведінка кодування за замовчуванням у Windows PowerShell :
На жаль, кодування символів за замовчуванням, яке використовується в Windows PowerShell, є суперечливим; Кроссплатформенне видання PowerShell Core , як обговорювалось у попередньому розділі, похвалило це і закінчило.
Примітка:
Наведене не прагне охоплювати всі стандартні командлети.
Прогугливання імен командлетів для пошуку тем довідки тепер показує версію тем PowerShell Core за замовчуванням; скористайтеся розкривним списком версій над списком тем ліворуч, щоб перейти до версії Windows PowerShell .
На момент написання цієї статті документація часто неправильно стверджує, що ASCII є кодуванням за замовчуванням у Windows PowerShell - див. Цю проблему з документами GitHub .
Командлети, які пишуть :
Out-File
та >
/ >>
створити "Unicode" - UTF-16LE - файли за замовчуванням - в яких кожен символ діапазону ASCII (теж) представлений 2 байтами - що помітно відрізняється від Set-Content
/ Add-Content
(див. наступний пункт); New-ModuleManifest
а Export-CliXml
також створювати файли UTF-16LE.
Set-Content
(і Add-Content
якщо файл ще не існує / порожній) використовує кодування ANSI (кодування, визначене застарілою кодовою сторінкою ANSI активної локалі, яку викликає PowerShell Default
).
Export-Csv
справді створює файли ASCII, як це задокументовано, але дивіться примітки, -Append
наведені нижче.
Export-PSSession
створює файли UTF-8 із специфікацією за замовчуванням.
New-Item -Type File -Value
в даний час створює UTF-8 без специфікації (!).
Тема Send-MailMessage
довідки також стверджує, що кодування ASCII є за замовчуванням - я особисто не перевіряв це твердження.
Start-Transcript
незмінно створює файли UTF-8 за допомогою специфікації, але дивіться примітки, -Append
наведені нижче.
Команди Re, які додаються до існуючого файлу:
>>
/ Out-File -Append
Чи не робити НЕ спроби відповідати кодуванні файлу існуючого контенту . Тобто вони сліпо застосовують своє кодування за замовчуванням, якщо не вказано інше -Encoding
, що не є варіантом з >>
(крім опосередковано в PSv5.1 +, через $PSDefaultParameterValues
, як показано вище). Коротше кажучи: ви повинні знати кодування вмісту існуючого файлу та додати, використовуючи те саме кодування.
Add-Content
є похвальним винятком: за відсутності явного -Encoding
аргументу він виявляє існуюче кодування та автоматично застосовує його до нового вмісту. Дякую, js2010 . Зауважте, що в Windows PowerShell це означає, що застосовується кодування ANSI, якщо існуючий вміст не має специфікації, тоді як це UTF-8 у PowerShell Core.
Ця невідповідність між Out-File -Append
/ >>
та Add-Content
, яка також впливає на PowerShell Core , обговорюється в цьому випуску GitHub .
Export-Csv -Append
частково відповідає існуючому кодуванню: він сліпо додає UTF-8, якщо кодування існуючого файлу є будь-яким із ASCII / UTF-8 / ANSI, але правильно відповідає UTF-16LE та UTF-16BE.
Якщо сказати інакше: за відсутності специфікації, Export-Csv -Append
передбачається, що UTF-8 є, тоді як Add-Content
передбачає ANSI.
Start-Transcript -Append
частково відповідає існуючому кодуванню: воно правильно відповідає кодуванню зі специфікацією , але за замовчуванням кодування ASCII може мати втрати за відсутності такого.
Командлети, які читають (тобто кодування, що використовується за відсутності специфікації ):
Get-Content
і Import-PowerShellDataFile
за замовчуванням ANSI ( Default
), що узгоджується з Set-Content
.
ANSI - це також те, що за замовчуванням визначає сам механізм PowerShell, коли він читає вихідний код із файлів.
На відміну від цього Import-Csv
, Import-CliXml
і Select-String
припустимо , UTF-8 під час відсутності специфікації.
>
/>>
стали ефективними псевдоніми дляOut-File
5.1?