2016-05-02 3 views
6

Hier ist ein einfacher Perl-Skript, das eine utf-8-codierte Datei schreiben sollte:In welcher Codierung gibt Readpipe das Ergebnis eines ausgeführten Befehls zurück?

use warnings; 
use strict; 

open (my $out, '>:encoding(utf-8)', 'tree.out') or die; 

print $out readpipe ('tree ~'); 

close $out; 

I readpipe erwartet habe einen utf-8 kodierten String zurück, da LANG-en_US.UTF-8 gesetzt. Wenn man jedoch auf tree.out schaut (während man sicherstellt, dass der Editor es als utf-8-kodiert erkennt), zeigt es mir allen verstümmelten Text an.

Wenn ich die >:encoding(utf-8) in der Open-Anweisung zu >:encoding(latin-1) ändern, erstellt das Skript eine utf-8 Datei mit dem erwarteten Text.

Das ist alles ein bisschen seltsam für mich. Was ist die Erklärung für dieses Verhalten?

+0

Siehe [Enocde :: Locale] (https://metacpan.org/pod/Encode::Locale) für das Einbinden von Gebietsschemainformationen. Für Ihr aktuelles Problem: 'readpipe' gibt Bytes zurück (die bereits codiert sind) als UTF-8). PerlIO-Layer '>: encoding (utf-8)' wird es erneut kodieren, wenn Sie es in Datei drucken. Lösung: Konvertieren Sie die Byte-Zeichenfolge vor dem Drucken in die Datei in eine Perl-Zeichenfolge. Verwenden Sie zum Beispiel 'Encode :: decode()' –

Antwort

2

readpipe gibt eine Kette von undecodierten Bytes an Perl zurück. Wir wissen, dass diese Zeichenfolge UTF-8 codiert ist, aber Sie haben es Perl nicht gesagt.

Die E/A-Schicht in Ihrem Ausgabehandle verwendet diese Zeichenfolge, vorausgesetzt, es handelt sich um Unicode-Codepunkte und um sie als UTF-8-Byte neu zu codieren.

Der Grund dafür, dass der IO-Layer latin-1 scheinbar korrekt funktioniert, ist, dass er jedes undecodierte Byte unbelastet ausschreibt, weil die ersten 256 Unicode-Codepunkte gut mit latin-1 übereinstimmen.

Die richtige Sache zu tun wäre decode die Byte-String von readpipe in eine Code-Point-String zurückgegeben, vor der Zuführung zu einer IO-Layer. Die Aussage use open ':utf8', wie von Borodin erwähnt, sollte eine brauchbare Lösung sein, da readpipe speziell in der open manual page erwähnt wird.

+0

* ''readpipe' kehrt zu einer Bytefolge zurück. * * Würden Sie bitte auf die Dokumentation verweisen, die das so sagt? – Borodin

+0

@Borodin, ich würde gerne, leider habe ich Schwierigkeiten, irgendwelche Dokumente dafür zu finden, die reflektieren, dass es für die Post IO-Schichten Welt geändert worden ist. Ich frage mich, ob perl '' 'Befehlszeilenargument kann das Verhalten ändern, aber ich habe nicht überprüft. – tjd

+1

@Borodin [perlunicode: "Wenn Unicode nicht passiert"] (http://perldoc.perl.org/perlunicode.html#When-Unicode-Does-Not-Happen) – ThisSuitIsBlackNot

Verwandte Themen