2016-05-02 4 views
6

Вот простой скрипт, который Perl должен написать UTF-8 закодированный файл:В какой кодировке readpipe возвращает результат выполненной команды?

use warnings; 
use strict; 

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

print $out readpipe ('tree ~'); 

close $out; 

Я ожидал readpipe вернуть UTF-8 закодированную строку, так как LANG установлен в en_US.UTF-8. Тем не менее, глядя на tree.out (при этом убедитесь, что редактор распознает его как кодировку utf-8) показывает мне весь искаженный текст.

Если изменить >:encoding(utf-8) в открытом заявлении >:encoding(latin-1), сценарий создает UTF-8 файл с ожидаемым текста.

Это все немного странно для меня. Каково объяснение этого поведения?

+0

См. [Enocde :: Locale] (https://metacpan.org/pod/Encode::Locale), как включить информацию о локали. Для вашей текущей проблемы: 'readpipe' возвращает байты (которые будут уже закодированы как UTF-8). PerlIO layer '>: encoding (utf-8)' будет закодировать его еще раз, когда вы напечатаете его в файл. Преобразование строки байта в строку Perl перед печатью в файл. Например, используйте 'Encode :: decode()' –

ответ

2

readpipe возвращает perl строку неуказанных байтов. Мы знаем, что эта строка кодируется в кодировке UTF-8, но вы не сказали Perl.

Уровень ввода-вывода на вашем дескрипторе вывода принимает эту строку, считая ее кодовыми точками Юникода и перекодируя их как байты UTF-8.

Причина, по которой уровень латинского ввода 1-го уровня функционирует правильно, заключается в том, что он выдает каждый незакодированный байт без возможности восстановления, потому что первые 256 кодов Unicode хорошо согласуются с латинским-1.

Правильная вещь должна состоять в том, чтобы decode байт-строка, возвращаемая readpipe, в кодовую строку, прежде чем подавать ее на слой ввода-вывода. Заявление use open ':utf8', как упоминалось Бородина, должно быть жизнеспособным решением, так как readpipe конкретно упоминается в open manual page.

+0

* "' readpipe' возвращает perl строку байтов "* Пожалуйста, ссылку на документацию, которая так говорит? – Borodin

+0

@Borodin, я бы с удовольствием, к сожалению, у меня возникли проблемы с поиском каких-либо документов для него, которые отражают, что он был изменен для мира сообщений IO-слоев. Интересно, может ли аргумент командной строки Perl '-C' изменить его поведение, но я не проверял. – tjd

+1

@Borodin [perlunicode: «Когда Unicode не происходит»] (http://perldoc.perl.org/perlunicode.html#When-Unicode-Does-Not-Happen) – ThisSuitIsBlackNot

Смежные вопросы