“Tail -f | iconv -fsjis "non genera nulla


14

Voglio tail -fun file, ma il suo contenuto è in sjiscodifica, quindi devo convertirlo nella codifica nativa (utf-8) del mio terminale.

Quando io faccio

tail -fx | iconv -fsjis

non ci sarà output. Come

coda x | iconv -fsjis

funziona, inizialmente ho pensato che fosse un problema di buffering, ma provare unbuffere stdbufcome descritto su Disattiva buffering in pipe non ha aiutato.

In effetti, anche dopo che più di 10k di dati fossero stati aggiunti a x, non ci sarebbe stato alcun output, quindi suppongo che non si tratti di un problema di buffering (il buffer è 4k, se non sbaglio), ma iconv inizierà a produrre solo quando riceve un EOF.

Quindi, come posso seguire la coda del mio file codificato SJIS?

Risposte:


11

(prendilo con un pizzico di sale) Per quanto mi ricordo, il problema sta nel modo in cui libiconvfunziona. Le codifiche multi-byte hanno bisogno di una macchina a stati per decodificarle e libiconvpreferiscono ricevere interi caratteri, quindi non puoi dargli solo metà carattere in una chiamata di funzione e l'altra metà nella successiva.

Mi vengono in mente altre due soluzioni, una è un buon metodo fuori banda, l'altra è un hack in banda.

Modifica codifica dell'emulatore terminale (fuori banda) : si deve cambiare la codifica dei caratteri nell'emulatore terminale, quindi la sua codifica nativa è Shift JIS. Ho appena controllato konsolee supporta questo. Dal menu Visualizza → Codifica caratteri → Giapponese → sjis. È quindi possibile solo tail -fil file e konsolesi occuperà di decodificare i caratteri multibyte e abbinarli a glifi dei caratteri.

Codifica terminale transcodifica al volo (in banda; migliore) : per gentile concessione di Gilles, che mi ha ricordato luitdopo molto tempo. Usa luit, che avrebbe dovuto venire con la tua distribuzione XOrg (su Debian, è un pacchetto x11-utils). Usalo in questo modo:

$ luit -encoding SJIS -- tail -f x

Ciò renderà il terminale transcodificare SJIS da / verso la codifica del terminale ed eseguirà tail -f x. Il rovescio della medaglia di luitè che non supporta la ricchezza di codifiche supportate da libiconv. Il lato positivo è che è disponibile quasi ovunque.

Transcodifica al volo del terminale (in-band; hack) : ttyconvè un trucco che ho scritto molti anni fa (inizialmente in C, poi rifatto in Python) che usa libiconvper transcodificare l'I / O del terminale. Genera un nuovo pseudoterminale e (a) transcodifica i caratteri digitati dalla codifica locale nella codifica remota e (b) transcodifica i caratteri ricevuti dalla codifica remota nella codifica locale. L'ho usato per parlare con server che utilizzavano codifiche non supportate dai terminali Linux standard. Si noti che tutte le codifiche remote con cui l'ho testato erano codifiche a byte singolo, quindi non posso garantire che funzioni per Shift JIS. Non trovo spesso chiamate per usarlo in questi giorni, con la maggior parte dei sistemi che passano a Unicode.

Ecco come lo useresti:

$ ttyconv -rsjis -- tail -f x

Il rovescio della medaglia ttyconvè che l'ho scritto, nessuno lo usa tranne me, è probabilmente pieno di bug. Eccello in questo. Il lato positivo è che utilizza libiconv, quindi se la tua codifica è insolita, è la soluzione migliore. All'ultimo conteggio, ttyconv --listsupporta 100 codifiche.


Fantastico, grazie. out-of-band non ha funzionato per me (gnome-terminal, anche se ti permette di cambiare la codifica), ma ttyconv funziona come un incantesimo.
Eugene Beresovsky,

2
In questi giorni, c'è luitparte della suite di utility X11 standard, che è simile alla tua ttyconv.
Gilles 'SO- smetti di essere malvagio' il

@Gilles luitè simile, tranne per il fatto che funziona molto meglio del mio. ;) Grazie! Questo è il motivo per cui ho smesso di usare in primo luogo. Nei 12 anni successivi sono riuscito a dimenticare anche il nome del comando e da allora lo cerco.
Alexios,

@Gilles luitfunziona anche per me. Perché non la rendi una risposta "ufficiale"? Faceva parte della mia installazione (debian), quindi è il più facile da usare per me.
Eugene Beresovsky

1
Ho aggiornato la risposta per includerla luitcome la scelta migliore per SJIS. Purtroppo, sembra che non supporti tutte le codifiche libiconv. Sembra che debba ancora usare la mia soluzione per i miei scopi surreali. :)
Alexios

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.