Solución:
Nota: con respecto a Comandos de PowerShell por sí solo, solo importa la elección de la fuente, suponiendo que los archivos de código fuente estén codificados correctamente; con respecto a programas externos, $OutputEncoding
, [Console]::InputEncoding
y [Console]::OutputEncoding
también importa.
los Potencia Shell Centro (v6 +) perspectiva (consulte la siguiente sección para Windows PowerShell), independientemente de su carácter representación problemas (también cubiertos en la siguiente sección), con respecto a la comunicación con programas externos:
-
Sobre Unix-como plataformas, PowerShell Core es Compatible con UTF-8 por defecto (normalmente, en estos días, dado que las plataformas modernas tipo Unix usan configuraciones regionales basadas en UTF-8).
-
Sobre Ventanas, es el legado configuración regional del sistema, a través de su Página de códigos OEM, que determina la codificación predeterminada en todas las consolas, incluidas las ventanas de consola Windows PowerShell y PowerShell Core, aunque las versiones recientes de Windows 10 ahora permiten configurar la configuración regional del sistema en la página de códigos
65001
(UTF-8) (la función aún está en versión beta a partir de la versión 1909 de Windows 10).-
Si usa esa función, PowerShell Centro las ventanas de la consola serán automáticamente compatibles con UTF-8, aunque en Windows PowerShell todavía tendrás que configurar
$OutputEncoding
a UTF-8 también (que en Core ya está predeterminado en UTF-8), como se muestra a continuación. -
De lo contrario, especialmente en versiones anteriores de Windows, puede utilizar el mismo enfoque que se detalla a continuación para Windows PowerShell.
-
Haciendo tu Windows PowerShell ventana de consola compatible con Unicode (UTF-8):
-
Elige un Tipo verdadero (TT) fuente que apoya el especifico guiones (sistemas de escritura, alfabetos) cuyos caracteres desea mostrar correctamente en la consola:
-
Importante: Tiempo todas las fuentes TrueType son compatibles con Unicode en principio, ellos Por lo general, solo admite un subconjunto de todos los caracteres Unicode, es decir, los correspondientes a guiones (sistemas de escritura), como la escritura latina, la escritura cirílica (rusa), …
En su caso particular, si debe admitir caracteres árabes, chinos, japoneses y rusos, su única opción esSimSun-ExtB
, que está disponible en Solo Windows 10.
Consulte Wikipedia para obtener una lista de las fuentes de Windows destinadas a qué scripts (alfabetos). -
Para cambiar la fuente, haga clic en el icono en la esquina superior izquierda de la ventana y seleccione
Properties
, luego cambie alFonts
pestaña y seleccione la fuente TrueType que le interese.- Vea esta respuesta SU de not2quibit para saber cómo hacer que las fuentes adicionales estén disponibles.
-
-
Además, para una comunicación adecuada con programas externos:
-
los la página de códigos de la ventana de la consola debe cambiarse a
65001
, la página de códigos UTF-8 (que generalmente se hace conchcp 65001
, que, sin embargo, no se puede usar directamente desde una sesión de PowerShell[1], pero el siguiente comando de PowerShell tiene el mismo efecto). -
Se debe indicar a Windows PowerShell que use UTF-8 para comunicarse con utilidades externas también, tanto al enviar entrada de canalización para programas externos, a través de él
$OutputEncoding
variable de preferencia (al decodificar la salida de programas externos, es la codificación almacenada en[console]::OutputEncoding
que se aplica).
-
El siguiente encantamiento mágico en Windows PowerShell hace esto (como se indicó, este implícitamente realiza chcp 65001
):
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding =
New-Object System.Text.UTF8Encoding
Para persistir estos ajustes, es decir, para que sus futuras sesiones interactivas de PowerShell sean compatibles con UTF-8 de forma predeterminada, agregue el comando anterior a su $PROFILE
expediente.
Nota: Las versiones recientes de Windows 10 ahora permiten configurar el configuración regional del sistema a la página de códigos 65001
(UTF-8) (la función todavía está en beta a partir de la versión 1903 de Windows 10), lo que hace todos Las ventanas de la consola están predeterminadas en UTF-8, incluido Windows PowerShell.
Si usa esa función, la configuración [console]::InputEncoding
/ [console]::OutputEncoding
entonces ya no es estrictamente necesario, pero aún tendrá que configurar $OutputEncoding
(que no es necesario en PowerShell Centro, dónde $OutputEncoding
ya está predeterminado en UTF-8).
Importante:
-
Estas La configuración asume que las utilidades externas con las que se comunica esperan una entrada codificada en UTF-8 y producen una salida UTF-8..
- Las CLI escritas en Node.js cumplen ese criterio, por ejemplo.
- Los scripts de Python, si se escriben teniendo en cuenta la compatibilidad con UTF-8, también pueden manejar UTF-8.
-
Por el contrario, estos ajustes pueden rotura utilidades (más antiguas) que solo esperan una codificación de un solo byte como lo implica la página de códigos OEM heredada del sistema.
- Hasta Windows 8.1, esto incluso incluía utilidades estándar de Windows como
find.exe
yfindstr.exe
, que se han corregido en Windows 10. - Consulte la parte inferior de esta publicación para saber cómo evitar este problema cambiando a UTF-8 temporalmente, bajo demanda para invocar una utilidad determinada.
- Hasta Windows 8.1, esto incluso incluía utilidades estándar de Windows como
-
Esta configuración se aplica a solo programas externos y no están relacionados con las codificaciones que Cmdlets de PowerShell usar en la salida:
- Consulte esta respuesta para conocer las codificaciones de caracteres predeterminadas que utilizan los cmdlets de PowerShell; en resumen: si quieres cmdlets en Windows PowerShell por defecto a UTF-8 (que Potencia Shell [Core] v6 + lo hace de todos modos), agregue
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
para usted$PROFILE
, pero tenga en cuenta que esto afectará a todas las llamadas a cmdlets con un-Encoding
parámetro en sus sesiones, a menos que ese parámetro se use explícitamente; también tenga en cuenta que en Windows PowerShell invariablemente obtendrá archivos UTF-8 con BOM; a la inversa, en Potencia Shell [Core] v6 +, que por defecto es BOM-menos UTF-8 (ambos en ausencia de-Encoding
y con-Encoding utf8
, tendrías que usar'utf8BOM'
.
- Consulte esta respuesta para conocer las codificaciones de caracteres predeterminadas que utilizan los cmdlets de PowerShell; en resumen: si quieres cmdlets en Windows PowerShell por defecto a UTF-8 (que Potencia Shell [Core] v6 + lo hace de todos modos), agregue
Información de antecedentes opcional
Punta del sombrero a eryksun por todas sus aportaciones.
-
Mientras una fuente TrueType está activa, la ventana de la consola buffer conserva correctamente (no ASCII) caracteres Unicode. incluso si no lo hacen hacer correctamente; es decir, aunque puedan aparecer genéricamente como
?
, para indicar la falta de compatibilidad con la fuente actual, puede copiar pegar tales personajes en otros lugares sin pérdida de información, como señala eryksun. -
PowerShell es capaz de generar caracteres Unicode a la consola incluso sin haber cambiado a la página de códigos
65001
primero.
Sin embargo, eso por sí mismo no Garantice que otros programas puedan manejar dicha salida correctamente; consulte a continuación. -
Cuando se trata de comunicándose con programas externos vía stdout (tubería), PowersShell utiliza la codificación de caracteres especificada en el
$OutputEncoding
variable de preferencia, cuales por defecto es ASCII (!) en Windows PowerShell, lo que significa que todos los caracteres que no sean ASCII se transcriben a literal?
personajes, resultando en pérdida de información. (Por el contrario, de manera encomiable, PowerShell Centro (v6 +) ahora usa (sin BOM) UTF-8 como la codificación predeterminada, de manera consistente).- Por el contrario, sin embargo, pasando no ASCII argumentos (en lugar de salida estándar (canalizada)) a programas externos parece requerir no configuración especial (no me queda claro por qué funciona); por ejemplo, el siguiente comando de Node.js devuelve correctamente
€: 1
incluso con la configuración predeterminada:node -pe "process.argv[1] + ': ' + process.argv[1].length" €
- Por el contrario, sin embargo, pasando no ASCII argumentos (en lugar de salida estándar (canalizada)) a programas externos parece requerir no configuración especial (no me queda claro por qué funciona); por ejemplo, el siguiente comando de Node.js devuelve correctamente
-
[Console]::OutputEncoding
:- controla qué codificación de caracteres se asume cuando la consola traduce la salida del programa en caracteres de visualización de la consola.
- además dice Potencia Shell qué codificación asumir cuando captura de salida de un programa externo.
El resultado es que si necesitas captura de salida desde un programa de producción de UTF-8, debe configurar[Console]::OutputEncoding
a UTF-8 también; configuración$OutputEncoding
solo cubre el aporte (al programa externo) aspecto.
-
[Console]::InputEncoding
establece la codificación para entrada de teclado en una consola[2] y también determina cómo la CLI de PowerShell interpreta los datos que recibe a través de stdin (entrada estándar). -
Si cambia la consola a UTF-8 para sesión completa no es una opción, puedes hacerlo temporalmente, para una llamada determinada:
# Save the current settings and temporarily switch to UTF-8. $oldOutputEncoding = $OutputEncoding; $oldConsoleEncoding = [Console]::OutputEncoding $OutputEncoding = [Console]::OutputEncoding = New-Object System.Text.Utf8Encoding # Call the UTF-8 program, using Node.js as an example. # This should echo '€' (`U+20AC`) as-is and report the length as *1*. $captured = '€' | node -pe "require('fs').readFileSync(0).toString().trim()" $captured; $captured.Length # Restore the previous settings. $OutputEncoding = $oldOutputEncoding; [Console]::OutputEncoding = $oldConsoleEncoding
-
Problemas en versiones anteriores de Windows (anteriores a W10):
- Un activo
chcp
valor de65001
romper la salida de la consola de algunos programas externos e incluso los archivos por lotes en general en versiones anteriores de Windows puede, en última instancia, deberse a un error en elWriteFile()
Función de la API de Windows (como también la usa la biblioteca C estándar), que informó erróneamente el número de caracteres en vez de bytes con página de códigos65001
en efecto, como se discutió en esta publicación de blog.
- Un activo
-
Los síntomas resultantes, según un comentario de bobince sobre esta respuesta de 2008, son: “Tengo entendido que las llamadas que devuelven un número de bytes (como fread / fwrite / etc) en realidad devuelven un número de caracteres. Esto provoca una amplia una variedad de síntomas, como lectura de entrada incompleta, bloqueos, archivos por lotes rotos, etc. “
Alternativas superiores a la consola nativa de Windows (terminal), conhost.exe
eryksun sugiere dos alternativas a las ventanas nativas de la consola de Windows (conhost.exe
), que proveedor carácter Unicode mejor y más rápido representación, debido al uso de la moderna API DirectWrite / DirectX acelerada por GPU en lugar de la “antigua implementación de GDI [that] no puede manejar scripts complejos, caracteres que no son BMP o fuentes de respaldo automáticas “.
-
El próximo, de código abierto de Microsoft Terminal de Windows, que se distribuirá y actualizará a través de Microsoft Store en Windows 10; consulte aquí para obtener una introducción.
-
Alternativa de terceros establecida desde hace mucho tiempo ConEmu, que tiene la ventaja de funcionar también en versiones anteriores de Windows.
[1] Tenga en cuenta que correr chcp 65001
de dentro una sesión de PowerShell es no eficaz, porque .NET cachés la codificación de salida de la consola en el inicio y desconoce los cambios posteriores realizados con chcp
(solo cambios realizados directamente a través de [console]::OutputEncoding]
son recogidos).
[2] No tengo claro cómo se manifiesta eso en la práctica; díganos, si sabe.
Elaboró la respuesta de Alexander Martin. Para propósitos de prueba, he creado algunas carpetas y archivos con nombres válidos de diferentes subrangos Unicode de la siguiente manera:
Por ejemplo, con Courier Nuevo fuente de la consola, los símbolos de reemplazo se muestran en lugar de los caracteres CJK en una consola PowerShell:
Por otro lado, con SimSun fuente de la consola, los símbolos de reemplazo (poco visibles) se muestran en lugar de los caracteres árabes y hebreos, mientras que los caracteres CJK parecen mostrarse correctamente:
Tenga en cuenta que todos los símbolos de reemplazo son simplemente desplegado mientras que los personajes reales se conservan como puede ver en el siguiente Copiar pegar desde arriba de la consola de PowerShell:
PS D:PShell> (Get-ChildItem 'D:batUnASCII Names' -Dir).Name
Arabic (عَرَبِيّ)
CJK (中文(繁體))
Czech (Čeština)
Greek (Γρεεκ)
Hebrew (עִבְרִית)
Japanese (日本語)
MathBoldScript ()
Russian (русский язык)
Türkçe (Türkiye)
‹angles›
☺☻♥♦
En aras de la integridad, estos son los valores de registro apropiados para habilitar más fuentes para el símbolo del sistema de Windows (esto también funciona para la consola de Windows PowerShell):
(Get-ItemProperty 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionConsoleTrueTypeFont' |
Select-Object -Property [0-9]* | Out-String).Split(
[System.Environment]::NewLine,
[System.StringSplitOptions]::RemoveEmptyEntries) |
Sort-Object
Salida de muestra:
0 : Consolas
00 : Source Code Pro
000 : DejaVu Sans Mono
0000 : Courier New
00000 : Simplified Arabic Fixed
000000 : Unifont
0000000 : Lucida Console
932 : *MS ゴシック
936 : *新宋体
Comentarios y valoraciones
Si tienes alguna sospecha o capacidad de acrecentar nuestro tutorial puedes añadir una crónica y con gusto lo interpretaremos.