Het veranderen van PowerShell standaard output encoding UTF-8

Standaard, wanneer u het omleiden van de output van een commando naar een bestand of pijp in iets anders, in PowerShell, wordt de codering UTF-16, dat is niet handig. Ik ben op zoek om het te veranderen naar UTF-8.

Het kan gedaan worden op een case-by-case basis door het vervangen van de >foo.txt syntaxis met | out-file foo.txt -encoding utf8 maar dit is lastig om te moeten herhalen elke keer.

De hardnekkige manier om dingen in PowerShell is om ze in \Users\me\Documents\WindowsPowerShell\profile.ps1; ik heb gecontroleerd of dit bestand wordt inderdaad uitgevoerd bij het opstarten.

Er is gezegd dat de uitgang van de codering kan worden ingesteld met $PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'} maar ik heb het geprobeerd en het had geen effect.

https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/ die vertelt over $OutputEncoding ziet er op het eerste gezicht als al moet worden betrokken, maar dan gaat het over de uitvoer wordt gecodeerd in de indeling ASCII, dat is niet wat er nu eigenlijk gebeurt.

Hoe zet u PowerShell te gebruiken UTF-8?

InformationsquelleAutor rwallace | 2016-10-18



One Reply
  1. 96

    Opmerking: Het onderstaande is van toepassing op Windows PowerShell. Zie de volgende sectie voor het cross-platform PowerShell Core editie.

    • Op PSv5.1 of hoger, waar > en >> effectief zijn aliassen van Out-File, kunt u de standaard codering voor > />> /Out-File via de $PSDefaultParameterValues voorkeur variabele:

      • $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
    • Op PSv5.0 of onder, u niet de codering wijzigen voor > />>, maar op PSv3 of hoger, de bovenstaande techniek werkt voor oproepen naar Out-File.

      (De $PSDefaultParameterValues voorkeur variabele werd geïntroduceerd in PSv3.0).

    • Op PSv3.0 of hoger, als u wilt de standaard codering voor alle cmdlets die ondersteuning

      een -Encoding parameter
      (die in PSv5.1+ bevat > en >>), gebruik:

      • $PSDefaultParameterValues['*:Encoding'] = 'utf8'

    Als u deze opdracht in uw $PROFILE, cmdlets dergelijke als Out-File en Set-Content zal het gebruik van UTF-8-codering standaard, maar let op: dit maakt het een sessie-algemene instelling die van invloed zijn op alle commando ‘ s /scripts die niet uitdrukkelijk aan te geven dat een codering.

    Ook zorg ervoor dat je deze commando ‘ s in uw scripts of modules die u wilt gedragen zich op dezelfde manier, dus dat ze inderdaad gedragen zich op dezelfde manier, zelfs als deze worden uitgevoerd door een andere gebruiker of een ander apparaat.

    Voorbehoud: PowerShell, als van v5.1, steevast maakt UTF-8 bestanden met een (pseudo -) BOM, dat is gebruikelijk alleen in de Windows wereld – Unix-gebaseerde hulpprogramma ‘ s niet herkent deze BOM (zie onderaan).

    Voor een overzicht van de wild inconsistente standaard karakter codering gedrag in veel van de Windows PowerShell-standaard-cmdlets, zie de onderste sectie.


    De automatische $OutputEncoding variabele is niets, en is alleen van toepassing op hoe PowerShell communiceert met externe programma ‘ s (wat codering PowerShell gebruikt bij het verzenden van strings tot hen) – het heeft niets te maken met de codering die de output redirection operatoren en PowerShell-cmdlets gebruiken voor het opslaan van bestanden.


    Optioneel te lezen: De cross-platform perspectief: PowerShell Core:

    PowerShell is nu cross-platform, via de PowerShell Core editie, waarvan de codering – verstandig – standaard BOM-minder UTF-8, in lijn met de Unix-achtige platformen.

    • Dit betekent dat de source code bestanden zonder een BOM wordt uitgegaan van de UTF-8, en het gebruik van > /Out-File /Set-Content standaard BOM-minder UTF-8; expliciete gebruik van de utf8 -Encoding argument ook maakt BOM-minder UTF-8, maar u kunt ervoor kiezen om bestanden te maken met de pseudo-BOM met de utf8bom waarde.

    • Als u het maken van PowerShell scripts met een editor op een Unix-achtig platform en tegenwoordig zelfs op Windows met cross-platform editors zoals Visual Studio Code en Sublieme Tekst, de resulterende *.ps1 bestand wordt meestal niet een UTF-8 pseudo-BOM:

      • Dit werkt prima op PowerShell Core.
      • Het kan breken op Windows PowerShell, indien het bestand bevat niet-ASCII-karakters; als je het nodig hebt voor het gebruik van niet-ASCII-tekens in uw scripts opslaan als UTF-8 met BOM.

        Zonder de BOM, Windows PowerShell (mis)interpreteert uw script als dat wordt gecodeerd in de legacy “ANSI” codepage (bepaald door de landinstellingen voor pre-Unicode-toepassingen; bijvoorbeeld, een Windows-1252 op de US-engels-systemen).
    • Omgekeerd, bestanden die doen de UTF-8 pseudo-BOM kan problematisch zijn op Unix-achtige platformen, zoals ze veroorzaken Unix-utilities zoals cat, sed, en awk – en zelfs sommige editors zoals gedit te passeren de pseudo-BOM door, ofwel, om het te behandelen als gegevens.

      • Dit kan niet altijd een probleem, maar kan zeker worden, zoals wanneer u probeert om een bestand te lezen in een string in bash met, zeg, text=$(cat file) of text=$(<file) – de resulterende variabele bevat de pseudo-BOM als de eerste 3 bytes.

    Inconsistente standaard codering gedrag in Windows PowerShell:

    Helaas, de standaard voor tekencodering wordt gebruikt in Windows PowerShell is wild inconsistent; de cross-platform PowerShell Core edition, zoals besproken in de vorige paragraaf, heeft commendably zetten en een einde te maken aan deze.

    Opmerking:

    • De volgende niet probeert te dekken alle standaard-cmdlets.

    • Googlen cmdlet namen te vinden van hun help-onderwerpen toont nu de PowerShell Core versie van de onderwerpen standaard; gebruik de versie in de vervolgkeuzelijst boven aan de lijst van onderwerpen op de links om te schakelen naar een Windows PowerShell versie.

    • Van dit schrijven, de documentatie vaak beweert ten onrechte dat ASCII is de standaard tekenset in Windows PowerShell – zie dit GitHub docs probleem.


    Cmdlets die schrijven:

    Out-File en > />> maken “Unicode” – UTF-16LE – bestanden standaard – in die elke ASCII-bereik karakter (ook) wordt vertegenwoordigd door 2 bytes – die beduidend verschilt van Set-Content /Add-Content (zie volgende punt); New-ModuleManifest en Export-CliXml ook UTF-16LE bestanden.

    Set-Content (en Add-Content als het bestand nog niet bestaat /is leeg) maakt gebruik van ANSI-codering (de codering gespecificeerd door het actieve systeem locale ‘ s ANSI legacy code pagina, PowerShell oproepen Default).

    Export-Csv inderdaad maakt ASCII-bestanden, zoals gedocumenteerd, maar zie de opmerkingen re -Append hieronder.

    Export-PSSession maakt UTF-8 bestanden met BOM standaard.

    New-Item -Type File -Value maakt op dit moment de BOM-minder(!) UTF-8.

    De Send-MailMessage help-onderwerp beweert ook dat de ASCII-codering is de standaard – ik heb niet persoonlijk geverifieerd dat de vordering.

    Opnieuw opdrachten die toevoegen aan een bestaand bestand:

    >> /Out-File -Append maken geen poging om de codering van een bestand bestaande inhoud.
    Dat is, ze blindelings hun standaard codering, tenzij anders overeengekomen met -Encoding, dat is geen optie met >> (met uitzondering van indirect in PSv5.1+, via $PSDefaultParameterValues, zoals hierboven weergegeven).
    In het kort: u moet weten dat de codering van een bestaand bestand en de inhoud toevoegen met behulp van dezelfde codering.

    Add-Content is de prijzenswaardige uitzondering: in de afwezigheid van een expliciete -Encoding argument, detecteert de bestaande codering en past automatisch aan de nieuwe inhoud.Bedankt, js2010. Merk op dat in Windows PowerShell dit betekent dat het ANSI-codering die wordt toegepast indien de bestaande inhoud geen BOM, terwijl de UTF-8 in PowerShell Kern.

    Deze inconsistentie tussen Out-File -Append />> en Add-Content, die ook van invloed PowerShell Core, wordt besproken in dit GitHub issue.

    Export-Csv -Append gedeeltelijk overeenkomt met de bestaande codering: het blindelings voegt UTF-8 als het bestaande bestand codering is een van ASCII of UTF-8/ANSI, maar juist overeenkomt met de UTF-16LE en UTF-16BE.

    Anders gezegd: in de afwezigheid van een BOM, Export-Csv -Append neemt UTF-8 is, terwijl Add-Content neemt ANSI.


    Cmdlets die lees (codering wordt gebruikt in de afwezigheid van een BOM):

    Get-Content en Import-PowerShellDataFile standaard ANSI (Default), die in overeenstemming is met Set-Content.

    ANSI is ook wat de PowerShell motor zelf de standaardinstellingen wanneer het leest broncode van bestanden.

    Door contrast, Import-Csv, Import-CliXml en Select-String stel UTF-8 in de afwezigheid van een BOM.

    • Kunt u uitleggen hoe>/>> van kracht werd aliassen voor Out-File in 5.1?
    • Het kan zijn PetSerAl die wees het aan mij, maar ik weet niet meer waar en hoe. Windows PowerShell is gesloten bron, maar aangezien het quasi-alias relatie geldt voor PowerShell Kern ook, je moet in staat zijn om het te vinden in de laatste de broncode.
    • Is er een manier om kracht om niet vooraan te BOM op Win10?
    • In Windows PowerShell, kunt u niet – u moet doorgaan met uw eigen output-functie zie stackoverflow.com/a/34969243/45375. In PowerShell Core (ook op Windows), BOM-minder is de standaardinstelling.
    • Het PS-6 dat is utf8nobom standaard. PS 5.1 is “ansi” voor de meeste commando ‘ s naast de out-bestand, dat is de “unicode”.
    • Helaas, het is veel ingewikkelder dan dat – zie het onderste deel heb ik net toegevoegd aan het antwoord. Daarnaast kunt u ook gebruik maken van de versie nummer te impliceren een PowerShell-editie (6 of hoger impliceert Core), het is duidelijker om te verwijzen naar hen als Windows PowerShell (alleen voor Windows), .NET Framework-gebaseerd) en PowerShell Core (cross-platform .NETTO-Core-based).
    • windows: wat een puinhoop
    • Ik weet niet eens, @EliaWeiss, maar het is Windows PowerShell-specifiek, en ze uiteindelijk deed het goed in de PowerShell Core.
    • Waarom windows moet een BOM te herkennen UTF-8 goed maar Linux niet? Het hele punt van UTF-8 IMHO is dat u niet-ASCII-tekens-en je geen zorgen over,
    • Windows besloten om te blijven backwards-compatible, wat betekent dat de bestanden die van zonder een BOM zijn standaard geïnterpreteerd als het gebruik van het systeem actief ANSI code page, ofwel, meestal met behulp van een enkel-byte -, 8-bits tekenset, zoals de Windows-1252 voor engels-talige systemen en veel West-Europese talen. Sinds de 8-bits bereik van deze coderingen is onverenigbaar met de UTF-8, moet u de STUKLIJST om onderscheid te maken. Bijvoorbeeld, een Windows-1252-gecodeerd bestand bevat karakter ü zou worden invalid wanneer geïnterpreteerd als UTF-8.
    • Vreemd, want ik kan het opslaan van een bestand in Windows als UTF-8 w/o BOM inclusief Japanse tekens en het opent fijn in kladblok, vscode enz.
    • VS Code en andere moderne cross-platform redactie commendably standaard UTF-8, die, echter, betekent dat ze verkeerd ANSI-gecodeerde bestanden. Kladblok gebruikt heuristiek gok, de codering. Het punt is dat het slechts een gok,, omdat UTF-8 gecodeerde bestand is ook een technisch geldig ANSI-gecodeerd bestand (maar niet vice versa). Het zou geweldig zijn als alles op Windows standaard UTF-8-in de afwezigheid van een BOM de manier waarop Unix-achtige platformen doen, maar dat is niet het geval, met name niet in Windows PowerShell, maar gelukkig is nu het geval in PowerShell Kern.
    • P. S.: Wanneer u een bestand in Kladblok vanuit het niets, het nog steeds standaard ANSI-codering.
    • Sinds ANSI is een subset van UTF-8 d.w.z. een geldig ANSI-bestand is een geldig UTF-8 ze niet “verkeerd” het precies is, maar we behandelen het als iets wat het niet is. Maar bedankt voor je verduidelijking. Ik ben het schrijven van een aanvraag voor “alle” platforms en ik zou graag om te kiezen voor een indeling die overal werkt. BOM-minder UTF-8 lijkt de weg te gaan. Nogmaals bedankt!
    • Ja, als je nodig hebt om cross-platform, BOM-minder UTF-8 is over het algemeen de beste keuze. Ik zie geen semantisch verschil tussen interpreteert en behandelen als iets het niet. ANSI niet een subset van UTF-8, alleen ASCII is. Daarom is een ANSI-bestand (met 8-bit-reeks tekens) geïnterpreteerd als UTF-8 zal er meestal toe leiden dat deze tekens worden beschouwd als invalid, en omgezet naar (U+FFFD), de VERVANGING KARAKTER
    • P. S., @Marc: Omgekeerd, een UTF-8-bestand geïnterpreteerd als ANSI zal resulteren in elk karakter buiten de ASCII-Unicode-assortiment wordt omgezet naar 2-4 niet-verwante tekens.
    • Uit-bestand toevoegen (of >>) mix 2 coderingen in hetzelfde bestand. Ik zou het niet gebruiken. Naast het unieke gebreke te unicode in PS 5.
    • Wat meer details. Blijkbaar out-bestand en > en >> bedoeld zijn om unix te kunnen nabootsen. github.com/PowerShell/PowerShell/issues/…
    • Bedankt, @js2010 – het antwoord bevat reeds een link naar uw probleem; mijn opmerking was niet bedoeld om te impliceren dat het emuleren van Unix was het ontwerp van de intentie – ik kan niet spreken over dat – ik was alleen op te wijzen dat in de Unix-wereld te >> blindelings geldt de standaard codering; ik ben het ermee eens dat Add-Content’s gedrag is meer nuttig.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *