Chci tail -f
soubor, ale jeho obsah je v sjis
kódování, takže jej musím převést na nativní (utf-8) kódování mého terminálu.
Když to udělám
ocas -f x | iconv -fsjis
nebude žádný výstup. Jako
ocas x | iconv -fsjis
funguje, zpočátku jsem si myslel, že jde o problém s ukládáním do vyrovnávací paměti, ale zkusil jsem unbuffer
a stdbuf
jak je popsáno v části Vypnutí ukládání do vyrovnávací paměti v potrubí nepomohlo.
Ve skutečnosti by i po přidání více než 10k dat do x nebyl žádný výstup, takže si myslím, že to není problém s vyrovnávací pamětí (vyrovnávací paměť je 4k, pokud se nepletu), ale iconv začne vydávat pouze tehdy, když obdrží EOF.
Jak tedy mohu sledovat svůj zakódovaný soubor sjis?
Přijatá odpověď:
(berte to se špetkou soli) Pokud si pamatuji, problém spočívá ve způsobu libiconv
funguje. Vícebajtová kódování potřebují k jejich dekódování stavový stroj a libiconv
preferuje přijímání celých znaků, takže mu nemůžete dát polovinu znaku v jednom volání funkce a druhou polovinu v dalším.
Napadají mě další dvě řešení, jedno je dobrá metoda mimo pásmo, druhé je in-band hack.
Změňte kódování emulátoru terminálu (mimo pásmo) :Jedním z nich je změnit kódování znaků v emulátoru terminálu, takže jeho nativní kódování je Shift JIS. Právě jsem zkontroloval konsole
a toto podporuje. V nabídce Zobrazit→Kódování znaků→Japonština→sjis. Pak stačí tail -f
soubor a konsole
se postará o dekódování vícebajtových znaků a jejich spárování s glyfy písem.
Překódování terminálového kódování za běhu (v pásmu; nejlepší) :s laskavým svolením Gillese, který mi připomněl luit
po velmi dlouhé době. Použijte luit
, který by měl být součástí vaší distribuce XOrg (v Debianu je to balíček x11-utils
). Použijte jej takto:
$ luit -encoding SJIS -- tail -f x
Tím se terminál překóduje SJIS do/z vašeho terminálového kódování a spustí se tail -f x
. Nevýhodou luit
je, že nepodporuje velké množství kódování podporovaných libiconv
. Výhodou je, že je k dispozici téměř všude.
Překódování terminálového kódování za chodu (v pásmu, hackování) :ttyconv
je hack, který jsem napsal před mnoha lety (zpočátku v C, později předělaný v Pythonu), který používá libiconv
překódovat I/O terminálu. Vytvoří nový pseudoterminál a (a) překóduje znaky, které napíšete z vašeho místního kódování do vzdáleného kódování, a (b) překóduje znaky, které přijmete ze vzdáleného kódování, do vašeho místního kódování. Použil jsem to, abych mluvil se servery, které používaly kódování nepodporované standardními linuxovými terminály. Vezměte prosím na vědomí, že všechna vzdálená kódování, se kterými jsem to testoval, byla jednobajtová kódování, takže nemohu zaručit, že bude fungovat pro Shift JIS. V dnešní době často nenacházím volání k použití, protože většina systémů přechází na Unicode.
Takto byste jej použili:
$ ttyconv -rsjis -- tail -f x
Nevýhoda ttyconv
je to, že jsem to napsal já, nikdo to nepoužívá, kromě mě, je to pravděpodobně plné chyb. V tomhle vynikám. Výhodou je, že používá libiconv
, takže pokud je vaše kódování neobvyklé, je to vaše nejlepší sázka. Při posledním počítání ttyconv --list
podporuje 100 kódování.