2014-09-03 7 views
5

Ich habe ein natives Programm in Python geschrieben, das seine Eingabe auf Stdin erwartet. Als einfaches Beispiel,Wie schiebe ich Unicode in eine native Anwendung in PowerShell

#!python3 
import sys 
with open('foo.txt', encoding='utf8') as f: 
    f.write(sys.stdin.read()) 

Ich möchte in der Lage, eine (Powershell) Zeichenfolge zu diesem Programm als Standardeingabe zu übergeben. Python erwartet seine Standardeingabe in der in $env:PYTHONIOENCODING angegebenen Codierung, die ich normalerweise auf UTF8 setzen werde (damit ich keine Codierungsfehler bekomme).

Aber egal was ich tue, Charaktere werden beschädigt. Ich habe das Netz gesucht und Vorschläge gefunden, um [Console]::InputEncoding/[Console]::OutputEncoding zu ändern, oder chcp zu verwenden, aber nichts scheint zu funktionieren.

Hier ist mein Basistest:

PS >[Console]::OutputEncoding.EncodingName 
Unicode (UTF-8) 
PS >[Console]::InputEncoding.EncodingName 
Unicode (UTF-8) 
PS >$env:PYTHONIOENCODING 
utf-8 
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())" 
´╗┐? 

PS >chcp 1252 
Active code page: 1252 
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())" 
? 

PS >chcp 65001 
Active code page: 65001 
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())" 
? 

Wie kann ich dieses Problem beheben?

Ich kann nicht einmal erklären, was hier vor sich geht. Grundsätzlich möchte ich beim Test (python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())") ein Eurozeichen ausdrucken. Und um zu verstehen, warum, muss ich tun, was benötigt wird, um das zu arbeiten :-) (Denn dann kann ich dieses Wissen in mein reales Szenario übersetzen, das in der Lage ist, Arbeits-Pipelines von Python-Programmen zu schreiben, die nicht ' t brechen, wenn sie auf Unicode-Zeichen stoßen).

+0

Haben Sie versucht, '$ OutputEncoding' einzustellen? –

+0

Noch schlimmer: ''> $ OutputEncoding = [Text.Encoding] :: UTF8 > $ env: PYTHONIOENCODING = "utf-8" > python -c "drucken ('\ N {Euro sign}')" | python -c "import sys; print (sys.stdin.read())" ∩╗┐╬ô├⌐┬╝''' (Sorry wegen der Formatierung, ich kann keine Zeilenumbrüche in einem Kommentar bekommen ...) –

+0

Ah, aber wenn ich auch [Console] :: OutputEncoding auf UTF8 setze, scheint das zu funktionieren! Kannst du erklären warum? Mir ist nicht klar, warum ich den Wert zweimal einstellen muss ... –

Antwort

3

Dank mike z, die folgenden Werke:

$OutputEncoding = [Console]::OutputEncoding = (new-object System.Text.UTF8Encoding $false) 
$env:PYTHONIOENCODING = "utf-8" 
python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())" 

Die new-object benötigt wird, um ohne BOM eine UTF-8 Codierung zu erhalten. Die $OutputEncoding Variable und [Console]::OutputEncoding scheinen beide gesetzt zu sein.

Ich verstehe immer noch nicht vollständig den Unterschied zwischen den beiden Kodierungswerten, und warum Sie sie jemals anders eingestellt haben (das scheint der Standard zu sein).