“Ekor -f | iconv -fsjis ”tidak menghasilkan apa-apa

14

Saya ingin tail -fsebuah file, tetapi isinya dalam sjispengkodean, jadi saya harus mengkonversinya ke pengkodean asli (utf-8) dari terminal saya.

Kapan saya melakukannya

tail -fx | iconv -fsjis

tidak akan ada output. Sebagai

ekor x | iconv -fsjis

tidak bekerja, pada awalnya saya pikir itu masalah buffering, tetapi mencoba unbufferdan stdbufseperti yang dijelaskan pada Matikan buffering di pipa tidak membantu.

Bahkan, bahkan setelah lebih dari 10k data ditambahkan ke x, tidak akan ada output, jadi saya kira itu bukan masalah buffering (buffer 4k, jika saya tidak salah), tetapi iconv hanya akan mulai menghasilkan ketika menerima EOF.

Jadi bagaimana saya bisa mengikuti file disandikan sjis saya?

Eugene Beresovsky
sumber

Jawaban:

11

(ambil ini dengan sejumput garam) Sejauh yang saya ingat, masalahnya terletak pada cara libiconvkerjanya. Pengkodean multi-byte memerlukan mesin keadaan untuk mendekode mereka, dan libiconvlebih suka menerima seluruh karakter, jadi Anda tidak bisa hanya memberikannya setengah karakter dalam satu panggilan fungsi dan setengah lainnya di berikutnya.

Saya bisa memikirkan dua solusi lain, satu adalah metode out-of-band yang bagus, yang lain adalah hack in-band.

Ubah pengkodean Terminal Emulator (out-of-band) : satu adalah untuk mengubah pengkodean karakter di terminal emulator Anda, sehingga pengkodean aslinya adalah Shift JIS. Saya baru saja memeriksa konsole, dan mendukung ini. Dari menu, Lihat → Pengkodean karakter → Japenese → sjis. Anda kemudian dapat hanya tail -ffile, dan konsoleakan mengurus decoding karakter multibyte dan mencocokkannya dengan font mesin terbang.

Pengkodean terminal transcode dengan cepat (in-band; terbaik) : milik Gilles, yang mengingatkan saya luitsetelah waktu yang sangat lama. Gunakan luit, yang seharusnya datang dengan distribusi XOrg Anda (pada Debian, paket itu x11-utils). Gunakan seperti ini:

$ luit -encoding SJIS -- tail -f x

Ini akan membuat terminal transcode SJIS ke / dari pengkodean terminal Anda, dan dijalankan tail -f x. Kelemahannya luitadalah tidak mendukung kekayaan pengkodean yang didukung oleh libiconv. Sisi baiknya adalah ini tersedia hampir di mana-mana.

Pengkodean terminal transcode saat itu juga (in-band; hack) : ttyconvadalah hack yang saya tulis bertahun-tahun yang lalu (awalnya dalam C, kemudian diulang dengan Python) yang digunakan libiconvuntuk transcode terminal I / O. Ini memunculkan pseudoterminal baru dan (a) mentranskode karakter yang Anda ketik dari pengkodean lokal ke dalam pengkodean jarak jauh, dan (b) mentranskode karakter yang Anda terima dari pengodean jauh ke pengodean lokal Anda. Saya menggunakannya untuk berbicara dengan server yang menggunakan penyandian yang tidak didukung oleh terminal Linux standar. Harap dicatat bahwa semua pengkodean jarak jauh yang saya uji dengan pengodean byte tunggal, jadi saya tidak dapat menjamin itu akan bekerja untuk Shift JIS. Saya tidak sering menemukan panggilan untuk menggunakannya hari ini, dengan sebagian besar sistem beralih ke Unicode.

Ini adalah bagaimana Anda akan menggunakannya:

$ ttyconv -rsjis -- tail -f x

Kelemahannya ttyconvadalah bahwa saya menulisnya, tidak ada yang menggunakannya kecuali saya, mungkin penuh dengan bug. Saya unggul dalam hal ini. Sisi positifnya adalah yang digunakannya libiconv, jadi jika pengkodean Anda tidak biasa, itu taruhan terbaik Anda. Pada hitungan terakhir, ttyconv --listmendukung 100 penyandian.

Alexios
sumber
Keren terima kasih. out-of-band tidak bekerja untuk saya (gnome-terminal, meskipun itu memungkinkan Anda untuk mengubah pengkodean), tetapi ttyconv bekerja seperti pesona.
Eugene Beresovsky
2
Saat ini, ada luit, bagian dari paket utilitas X11 standar, yang mirip dengan Anda ttyconv.
Gilles 'SO- stop being evil'
@Gilles luitmirip, kecuali bahwa itu bekerja jauh lebih baik daripada milikku. ;) Terima kasih! Inilah sebabnya saya berhenti menggunakan sejak awal. Dalam 12 tahun sejak saya berhasil melupakan bahkan nama perintah dan saya sudah mencarinya sejak itu.
Alexios
@Gilles luitbekerja untukku juga. Mengapa Anda tidak menjadikannya jawaban 'resmi'? Itu adalah bagian dari instalasi saya (debian), dan dengan demikian adalah yang paling mudah digunakan untuk saya.
Eugene Beresovsky
1
Saya memperbarui jawaban untuk dimasukkan luitsebagai pilihan terbaik untuk SJIS. Sayangnya, sepertinya tidak mendukung setiap encoding libiconv. Sepertinya saya masih harus menggunakan solusi saya sendiri untuk tujuan surealis saya sendiri. :)
Alexios