“ tail -f | iconv -fsjis” ไม่ส่งสัญญาณอะไรเลย


14

ฉันต้องการtail -fไฟล์ แต่เนื้อหาของมันกำลังอยู่ในการsjisเข้ารหัสดังนั้นฉันจึงต้องแปลงมันเป็นการเข้ารหัสเนทีฟ (utf-8) ของเทอร์มินัลของฉัน

เมื่อฉันทำ

tail -fx | iconv -fsjis

จะไม่มีเอาต์พุต เช่น

หาง x | iconv -fsjis

ใช้งานได้ในตอนแรกฉันคิดว่ามันเป็นปัญหาบัฟเฟอร์ แต่การลองunbufferและstdbufตามที่อธิบายไว้ในการปิดการบัฟเฟอร์ในไพพ์ไม่ได้ช่วยอะไร

ในความเป็นจริงแม้หลังจากเพิ่มข้อมูลมากกว่า 10k ลงใน x แล้วก็จะไม่มีเอาต์พุตดังนั้นฉันเดาว่ามันไม่ใช่ปัญหาบัฟเฟอร์ (บัฟเฟอร์คือ 4k ถ้าฉันไม่เข้าใจผิด) แต่ไอคอนvจะเริ่มแสดงผลเมื่อ มันได้รับ EOF

ดังนั้นฉันจะติดตามไฟล์เข้ารหัส sjis ของฉันได้อย่างไร

คำตอบ:


11

(เอาเกลือไปนิดหน่อย) เท่าที่ฉันจำได้ปัญหาอยู่ที่การlibiconvทำงาน การเข้ารหัสหลายไบต์ต้องใช้เครื่องรัฐในการถอดรหัสและlibiconvต้องการรับอักขระทั้งหมดดังนั้นคุณจึงไม่สามารถให้อักขระครึ่งตัวในการเรียกฟังก์ชันหนึ่งและอีกครึ่งหนึ่งในถัดไป

ฉันคิดว่าอีกสองวิธีแก้ปัญหาวิธีหนึ่งเป็นวิธีที่ดีนอกวงอีกวิธีหนึ่งคือการแฮ็กในวง

เปลี่ยนการเข้ารหัสเทอร์มินัลอีมูเลเตอร์ (out-of-band) : หนึ่งคือการเปลี่ยนการเข้ารหัสอักขระในเทอร์มินัลอีมูเลเตอร์ของคุณดังนั้นการเข้ารหัสเนทีฟจึงเป็น Shift JIS ฉันเพิ่งตรวจสอบkonsoleและรองรับสิ่งนี้ จากเมนูดู→การเข้ารหัสอักขระ→ Japenese → sjis จากนั้นคุณสามารถเพียงแค่tail -fไฟล์และkonsoleจะดูแลการถอดรหัสอักขระหลายไบต์และจับคู่พวกเขาจนถึงตัวอักษรร่ายมนตร์

การเข้ารหัสเทอร์มินัล Transcode ในทันที (ในวงดนตรี; ดีที่สุด) : ความอนุเคราะห์จาก Gilles ที่ทำให้ฉันนึกถึงluitหลังจากผ่านไปนานมาก ใช้luitซึ่งควรมาพร้อมกับการกระจาย XOrg ของคุณ (บน Debian มันเป็นแพ็คเกจx11-utils) ใช้มันแบบนี้:

$ luit -encoding SJIS -- tail -f x

นี้จะทำให้ SJIS แปลงขั้ว / จากการเข้ารหัส terminal tail -f xของคุณและการทำงาน ข้อเสียของluitlibiconvก็คือว่ามันไม่สนับสนุนความมั่งคั่งของการเข้ารหัสการสนับสนุนโดย ข้อเสียคือมันมีอยู่เกือบทุกที่

การเข้ารหัสเทอร์มินัล Transcode ในทันที (ในวงดนตรี; แฮ็ค) : ttyconvเป็นแฮ็คที่ฉันเขียนเมื่อหลายปีก่อน (เริ่มแรกใน C ต่อมาใหม่ใน Python) ซึ่งใช้libiconvในการแปลงขั้ว I / O มันจะสร้าง pseudoterminal ใหม่และ (a) แปลงอักขระที่คุณพิมพ์จากการเข้ารหัสในเครื่องของคุณเป็นการเข้ารหัสจากระยะไกลและ (b) แปลงรหัสอักขระที่คุณได้รับจากการเข้ารหัสระยะไกลเป็นการเข้ารหัสท้องถิ่นของคุณ ฉันใช้มันเพื่อพูดคุยกับเซิร์ฟเวอร์ที่ใช้การเข้ารหัสที่ไม่ได้รับการสนับสนุนจากเทอร์มินัล Linux มาตรฐาน โปรดทราบว่าการเข้ารหัสระยะไกลทั้งหมดที่ฉันทดสอบด้วยเป็นการเข้ารหัสไบต์เดียวดังนั้นฉันจึงไม่สามารถรับประกันได้ว่า Shift JIS จะทำงานได้ ฉันมักจะไม่พบการโทรเพื่อใช้งานในปัจจุบันด้วยระบบส่วนใหญ่เปลี่ยนเป็น Unicode

นี่คือวิธีที่คุณจะใช้:

$ ttyconv -rsjis -- tail -f x

ข้อเสียttyconvคือฉันเขียนมันไม่มีใครใช้มัน แต่ฉันก็อาจเต็มไปด้วยข้อบกพร่อง ฉันเก่งเรื่องนี้ ข้อดีคือมันใช้libiconvดังนั้นหากการเข้ารหัสของคุณผิดปกติมันเป็นทางออกที่ดีที่สุดของคุณ เมื่อนับครั้งล่าสุดttyconv --listรองรับการเข้ารหัส 100 รายการ


เยี่ยมมากขอบคุณ out-of-band ไม่ได้ผลสำหรับฉัน (gnome-terminal แม้ว่ามันจะอนุญาตให้คุณเปลี่ยนการเข้ารหัส) แต่ ttyconv ทำงานได้เหมือนมีเสน่ห์
Eugene Beresovsky

2
วันนี้มีเป็นluitส่วนหนึ่งของชุดยูทิลิตี้ X11 ttyconvมาตรฐานซึ่งจะคล้ายกับของคุณ
Gilles 'หยุดความชั่วร้าย'

@Gilles luitคล้ายกันยกเว้นว่าจะทำงานได้ดีกว่าของฉันมาก ;) ขอบคุณ! นี่คือเหตุผลที่ฉันหยุดใช้ในตอนแรก ในช่วง 12 ปีที่ผ่านมาฉันพยายามที่จะลืมแม้กระทั่งชื่อคำสั่งและฉันก็มองหามันตั้งแต่นั้นเป็นต้นมา
Alexios

@Gilles luitทำงานให้ฉันด้วย ทำไมคุณไม่ทำให้มันเป็นคำตอบ 'อย่างเป็นทางการ'? มันเป็นส่วนหนึ่งของการติดตั้งของฉัน (เดเบียน) และดังนั้นจึงเป็นวิธีที่ง่ายที่สุดสำหรับฉัน
Eugene Beresovsky

1
ฉันอัปเดตคำตอบเพื่อรวมluitเป็นตัวเลือกที่ดีที่สุดสำหรับ SJIS น่าเศร้าที่มันดูเหมือนว่ามันไม่สนับสนุนทุกการเข้ารหัสlibiconvไม่ ดูเหมือนว่าฉันยังต้องใช้โซลูชันของตัวเองเพื่อจุดประสงค์เหนือจริง :)
Alexios

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.