Примітка: Наступне стосується 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-File5.1?