ich habe ein Problem, das nur bei Verwendung der Windows PowerShell auftritt. Es geht darum, Daten von der Standardeingabe zu lesen und korrekt anzuzeigen.
Hier ein kleines Testprogramm (lauffähig unter Python 2 und Python 3), um das Problem besser nachvollziehen zu können:
Code: Alles auswählen
from __future__ import print_function
import sys
def print_stream(input_stream):
if hasattr(input_stream, 'buffer'):
# `buffer` is expected to provide the raw bytes.
# Prefer this over pre-encoded strings.
input_stream = input_stream.buffer
result = input_stream.read().rstrip()
if hasattr(sys.stdout, 'encoding') and isinstance(result, bytes):
# Python 3 prints `repr(result)` if `result` is a bytes type.
# Avoid that by converting `result` into a string.
result = result.decode(sys.stdout.encoding)
print(result)
if __name__ == '__main__':
print_stream(sys.stdin)
Zum Testen führe ich das Programm via ``echo späm | py -2 print_input.py`` bzw ``echo späm | py -3 print_input.py`` aus.
Bei Verwendung von `cmd.exe` erscheint erwartungsgemäß "späm" auf dem Bildschirm. Nutze ich jedoch die PowerShell, dann erscheint stattdessen "sp?m". Ganz offensichtlich gibt es hierbei also an irgendeiner Stelle ein Problem mit Umlauten, oder allgemeiner gesagt: mit Zeichen außerhalb von ASCII.
Eines noch als Anmerkung: Nach entsprechender Recherche habe ich herausgefunden, dass man dieses Problem umgehen kann, wenn man vorher den Befehl ``$OutputEncoding = [Console]::OutputEncoding`` ausführt. Wenn ich es richtig verstanden habe, dann nutzt die PowerShell für interne Umleitungen eine andere Kodierung als für die spätere Ausgabe. Mit anderen Worten: Das, was aus der Pipe kommt, ist anders kodiert als das, was am Ende in der Shell angezeigt wird. Und diese Diskrepanz gleicht man durch den besagten Befehl wieder aus.
Meine Frage ist nun: Wie kann ich innerhalb von Python (d.h. ohne vorherigen Shell-Befehl) dafür sorgen, dass auch Zeichen außerhalb von ASCII korrekt in der PowerShell angezeigt werden, wenn sie aus einer Pipe gelesen werden? Naheliegend wäre es wohl, das "OutputEncoding" auszulesen und dessen Wert beim Dekodieren in Python zu verwenden, damit man gar nicht erst etwas an dieser Variable verändern muss. Leider habe ich aber bisher nicht herausgefunden, wie dies funktioniert. Als "normale" Umgebungsvariable in `os.environ` taucht es zumindest nicht auf. Oder gibt es noch andere Vorschläge?
Für Hilfe wäre ich dankbar...