Подтвердить что ты не робот

Изменение кодировки по умолчанию для PowerShell для UTF-8

По умолчанию, когда вы перенаправляете вывод команды в файл или подключаете ее к чему-то еще в PowerShell, кодировка UTF-16, что не полезно. Я хочу изменить его на UTF-8.

Это можно сделать в каждом конкретном случае, заменив синтаксис >foo.txt на | out-file foo.txt -encoding utf8, но это неудобно повторять каждый раз.

Постоянный способ установить вещи в PowerShell - это поместить их в \Users\me\Documents\WindowsPowerShell\profile.ps1; Я проверил, что этот файл действительно выполняется при запуске.

Было сказано, что выходное кодирование может быть установлено с помощью $PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'}, но я пробовал это и не имел никакого эффекта.

https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/, в котором говорится о $OutputEncoding, на первый взгляд выглядит так, как если бы это было актуально, но тогда речь идет о кодировании вывода в ASCII, что не происходит на самом деле.

Как вы устанавливаете PowerShell для использования UTF-8?

4b9b3361

Ответ 1

Примечание. Следующее относится к Windows PowerShell. В следующем разделе приведена кроссплатформенная версия PowerShell Core.

  • На 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 PowerShell приведена в нижнем разделе.


Автоматическая переменная $OutputEncoding не имеет отношения и применяется только к тому, как PowerShell взаимодействует с внешними программами (какую кодировку использует PowerShell при отправке им строк) - она не имеет ничего общего с кодировкой, которую используют операторы перенаправления вывода и командлеты PowerShell. используйте для сохранения в файлы.


Необязательное чтение: кроссплатформенная перспектива: PowerShell Core:

Теперь PowerShell является кроссплатформенным благодаря своей версии PowerShell Core, кодировка которой - - по умолчанию - по умолчанию без UTF-8, соответствующая Unix-подобным платформам.

  • Это означает, что файлы с исходным кодом без спецификации предполагаются как UTF-8, и с использованием >/Out-File/Set-Content по умолчанию используется UTF-8 без спецификации; явное использование аргумента utf8 -Encoding также создает UTF-8 без спецификации, но вы можете создать файлы с псевдо-спецификацией со значением utf8bom.

  • Если вы создаете сценарии PowerShell с редактором на Unix-подобной платформе, и в настоящее время даже в Windows с кроссплатформенными редакторами, такими как код Visual Studio и Sublime Text, результирующий файл *.ps1 обычно не будет иметь псевдо-спецификации UTF-8 :

    • Это отлично работает на PowerShell Core.
    • В Windows PowerShell может произойти сбой, если файл содержит символы, отличные от ASCII; если вам нужно использовать не-ASCII символы в ваших сценариях, сохраните их как UTF-8 с спецификацией.
      Без спецификации Windows PowerShell (ошибочно) интерпретирует ваш сценарий как закодированный в устаревшей кодовой странице "ANSI" (определяется системным языком для приложений, предшествующих Unicode; например, Windows-1252 в системах на американском и английском языках).
  • И наоборот, файлы с псевдо-спецификацией UTF-8 могут создавать проблемы на Unix-подобных платформах, так как они вызывают утилиты Unix, такие как cat, sed и awk - и даже некоторые редакторы, такие как gedit - для передачи псевдо-спецификации, т.е. для обработки ее как данных.

    • Это не всегда может быть проблемой, но определенно может быть, например, когда вы пытаетесь прочитать файл в строку в 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-ContentAdd-Content, если файл еще не существует/является пустым) использует кодировку ANSI (кодировку, заданную устаревшей кодовой страницей устаревшего языкового стандарта активной системы, которую PowerShell вызывает Default).

Export-Csv действительно создает файлы ASCII, как документировано, но см. примечания к -Append ниже.

Export-PSSession по умолчанию создает файлы UTF-8 с спецификацией.

New-Item -Type File -Value в настоящее время создает UTF-8 без BOM (!).

В справочной теме Send-MailMessage также утверждается, что кодировка ASCII используется по умолчанию - я лично не проверял это утверждение.

Re команды, которые добавляют в существующий файл:

>>/Out-File -Append не делают попыток сопоставить кодировку файла с существующим контентом. То есть они слепо применяют кодировку по умолчанию, если не указано иное с -Encoding, что не является опцией с >> (за исключением косвенного в PSv5. 1+ через $PSDefaultParameterValues, как показано выше). Вкратце: вы должны знать кодировку существующего содержимого файла и добавлять ее, используя ту же кодировку.

Add-Content является похвальным исключением: при отсутствии явного аргумента -Encoding он обнаруживает существующую кодировку и автоматически применяет его к новому контенту. Thanks, js2010. Обратите внимание, что в Windows PowerShell это означает, что это кодировка ANSI, которая применяется, если существующий контент не имеет спецификации, тогда как в PowerShell Core это UTF-8.

Это несоответствие между Out-File -Append/>> и Add-Content, которое также влияет на ядро PowerShell, обсуждается в этой проблеме GitHub.

Export-Csv -Append частично соответствует существующей кодировке: он слепо добавляет UTF-8, если существующая кодировка файла является любой из ASCII/UTF-8/ANSI, но правильно соответствует UTF-16LE и UTF-16BE.
Иными словами, в отсутствие спецификации Export-Csv -Append предполагает UTF-8, а Add-Content предполагает ANSI.


Командлеты, которые читают (кодировка, используемая при отсутствии спецификации):

Get-Content и Import-PowerShellDataFile по умолчанию используют ANSI (Default), что соответствует Set-Content.
Кроме того, ANSI по умолчанию использует механизм PowerShell при чтении исходного кода из файлов.

В отличие от этого, Import-Csv, Import-CliXml и Select-String предполагают UTF-8 в отсутствие спецификации.