„Tail -f | iconv -fsjis ”nic nie wyświetla

14

Chcę tail -fplik, ale jego zawartość jest sjiskodowana, więc muszę go przekonwertować na rodzime (utf-8) kodowanie mojego terminala.

Kiedy robię

tail -fx | iconv -fsjis

nie będzie wyjścia. Tak jak

ogon x | iconv -fsjis

działa, na początku myślałem, że to problem buforowania, ale próba unbufferi stdbufjak opisano w Wyłączanie buforowania w potoku nie pomogło.

W rzeczywistości, nawet po dodaniu do x więcej niż 10k danych, nie byłoby danych wyjściowych, więc myślę, że nie jest to problem z buforowaniem (bufor to 4k, jeśli się nie mylę), ale iconv zacznie generować, gdy otrzymuje EOF.

Jak mogę śledzić plik zakodowany w sjis?

Eugene Beresovsky
źródło

Odpowiedzi:

11

(weź to ze szczyptą soli) O ile pamiętam, problem polega na sposobie libiconvdziałania. Kodowanie wielobajtowe wymaga automatu stanów do ich dekodowania i libiconvwoli odbierać całe znaki, więc nie można po prostu nadać mu połowy znaku w jednym wywołaniu funkcji, a drugiej połowy w następnym.

Mogę wymyślić dwa inne rozwiązania, jedno jest dobrą metodą poza pasmem, drugie to hack wewnątrz pasma.

Zmień kodowanie emulatora terminala (poza pasmem) : jednym z nich jest zmiana kodowania znaków w emulatorze terminala, więc jego natywnym kodowaniem jest Shift JIS. Właśnie sprawdziłem konsolei obsługuje to. Z menu Widok → Kodowanie znaków → Japenese → sjis. Następnie możesz po prostu tail -fplik i konsolezajmie się dekodowaniem znaków wielobajtowych i dopasowaniem ich do glifów czcionek.

Kodowanie terminala transkodowanego w locie (w paśmie; najlepsze) : dzięki uprzejmości Gillesa, który przypomniał mi o luitbardzo długim czasie. Użyj luit, która powinna była pochodzić z twojej dystrybucji XOrg (na Debianie, jest to pakiet x11-utils). Użyj tego w ten sposób:

$ luit -encoding SJIS -- tail -f x

Spowoduje to, że terminal przekoduje SJIS do / z twojego terminala i uruchomi się tail -f x. Minusem luitjest to, że nie obsługuje bogactwa kodowania obsługiwanego przez libiconv. Plusem jest to, że jest dostępny prawie wszędzie.

Kodowanie terminala transkodowanego w locie (wewnątrz pasma; hack) : ttyconvto hack, który napisałem wiele lat temu (początkowo w C, a później przerobiony w Pythonie), który wykorzystuje libiconvdo transkodowania I / O terminala. Odradza się nowy pseudoterminal i (a) transkoduje znaki, które wpisujesz z lokalnego kodowania na kodowanie zdalne, i (b) transkoduje znaki, które otrzymujesz z kodowania zdalnego na kodowanie lokalne. Użyłem go do rozmowy z serwerami, które używały kodowania nieobsługiwanego przez standardowe terminale Linuksa. Pamiętaj, że wszystkie zdalne kodowania, z którymi go testowałem, były kodowaniami jednobajtowymi, więc nie mogę zagwarantować, że zadziała w Shift JIS. Obecnie często nie znajduję połączenia, aby z niego korzystać, ponieważ większość systemów przełącza się na Unicode.

Tak byś tego użył:

$ ttyconv -rsjis -- tail -f x

Minusem ttyconvjest to, że to napisałem, nikt tego nie używa, ale ja, prawdopodobnie jest pełen błędów. Celuję w tym. Zaletą jest to, że używa libiconv, więc jeśli twoje kodowanie jest nietypowe, jest to najlepszy wybór. W ostatniej liczbie ttyconv --listobsługuje 100 kodowań.

Alexios
źródło
Wielkie dzieki. out-of-band nie działał dla mnie (gnome-terminal, chociaż pozwala ci zmienić kodowanie), ale ttyconv działa jak urok.
Eugene Beresovsky,
2
Obecnie istnieje luitczęść standardowego pakietu narzędzi X11, który jest podobny do twojego ttyconv.
Gilles 'SO - przestań być zły'
@Gilles luitjest podobny, z tym wyjątkiem, że działa znacznie lepiej niż mój. ;) Dzięki! Właśnie dlatego przestałem używać. W ciągu 12 lat, od kiedy zdołałem zapomnieć nawet nazwę polecenia i od tego czasu jej szukam.
Alexios
@Gilles też luitdziała dla mnie. Dlaczego nie uczynisz tego „oficjalną” odpowiedzią? Była to część mojej instalacji (debian) i dlatego jest dla mnie najłatwiejsza w użyciu.
Eugene Beresovsky
1
Zaktualizowałem odpowiedź, aby uwzględnić ją luitjako najlepszy wybór dla SJIS. Niestety wygląda na to, że nie obsługuje każdego kodowania libiconv. Wygląda na to, że wciąż muszę używać własnego rozwiązania do własnych surrealistycznych celów. :)
Alexios,