"tail -f | iconv -fsjis" ничего не выводит

"tail -f | iconv -fsjis" ничего не выводит

Мне нужен tail -fфайл, но его содержимое закодировано sjis, поэтому мне нужно преобразовать его в собственную кодировку (utf-8) моего терминала.

Когда я делаю

хвост -fx | iconv -fsjis

не будет никакого выхода. Как

хвост x | iconv -fsjis

работает, сначала я думал, что это проблема буферизации, но попробовав unbufferи stdbufкак описано наОтключить буферизацию в каналене помогло.

На самом деле, даже после добавления более 10 КБ данных в x вывода не будет, поэтому я предполагаю, что это не проблема буферизации (буфер составляет 4 КБ, если я не ошибаюсь), но iconv начнет выводить данные только после получения EOF.

Итак, как мне отследить мой файл, закодированный в формате SJIS?

решение1

(отнеситесь к этому с долей скепсиса) Насколько я помню, проблема в том, как libiconvработает. Многобайтовые кодировки требуют конечного автомата для их декодирования и libiconvпредпочитают получать целые символы, так что вы не можете просто передать ему половину символа в одном вызове функции, а другую половину — в следующем.

Я могу придумать еще два решения: одно — хороший внеполосный метод, другое — внутриполосный хак.

Изменить кодировку эмулятора терминала (внеполосно): один из них — изменить кодировку символов в вашем эмуляторе терминала, чтобы его родная кодировка была Shift JIS. Я только что проверил konsole, и он поддерживает это. Из меню, Вид→Кодировка символов→Японский→sjis. Затем вы можете просто tail -fфайл, и konsoleон позаботится о декодировании многобайтовых символов и сопоставлении их с глифами шрифта.

Перекодирование терминального кодирования на лету (внутриполосное; лучшее): любезно предоставлено Жилем, который напомнил мне о luitпосле очень долгого перерыва. Используйте luit, который должен был быть в вашем дистрибутиве XOrg (в Debian это пакет x11-utils). Используйте его так:

$ luit -encoding SJIS -- tail -f x

Это заставит терминал перекодировать SJIS в/из кодировки вашего терминала и запустить tail -f x. Недостатком luitявляется то, что он не поддерживает множество кодировок, поддерживаемых libiconv. Преимуществом является то, что он доступен практически везде.

Перекодирование терминального кодирования на лету (внутриполосное; хак):ttyconvэто хак, который я написал много лет назад(первоначально на C, позже переделано на Python), который используется libiconvдля перекодирования терминального ввода-вывода. Он порождает новый псевдотерминал и (a) перекодирует символы, которые вы вводите, из вашей локальной кодировки в удаленную кодировку, и (b) перекодирует символы, которые вы получаете из удаленной кодировки в вашу локальную кодировку. Я использовал его для связи с серверами, которые использовали кодировки, не поддерживаемые стандартными терминалами Linux. Обратите внимание, что все удаленные кодировки, с которыми я его тестировал, были однобайтовыми кодировками, поэтому я не могу гарантировать, что он будет работать для Shift JIS. Я не часто нахожу необходимость использовать его в наши дни, поскольку большинство систем переходят на Unicode.

Вот как это можно использовать:

$ ttyconv -rsjis -- tail -f x

Недостаток в ttyconvтом, что я написал его, никто им не пользуется, кроме меня, он, вероятно, полон ошибок. Я преуспел в этом. Плюс в том, что он использует libiconv, так что если ваша кодировка необычная, это ваш лучший выбор. По последним подсчетам, ttyconv --listподдерживает 100 кодировок.

решение2

Похожая программа ttyconvесть также tconv, написанная на языке C Ричем Фелкером.

Видеть:Re: Призыв к исправлению aterm/rxvt/etc...

Связанный контент