สัญลักษณ์แปลก ๆ บนหน้าจอเมื่อใช้ grep?


12

./trans ... เอาต์พุตคำสั่งแสดงรหัสยกเว้น

มีความคิดอะไรที่ทำให้เกิดสิ่งนี้ สิ่งเดียวที่แสดงคือรหัส ISO และพื้นที่ว่างโดยไม่ใช้ grep

ซอฟต์แวร์ที่ใช้

คำสั่ง: ./trans --id --input /path/to/txt | grep ISO | grep [a-z]

root@box /test # alias grep
alias grep='grep --color=auto'
root@box /test # type grep
grep is aliased to `grep --color=auto'

เอาท์พุทปกติ:

เอาต์พุตคำสั่ง trans พร้อมข้อความที่อ่านได้และ URL


กรุณาวางออกแทนที่จะแนบภาพ เพื่อให้ผู้อื่นสามารถใช้คำสั่งการวางซ้ำเพื่อทำซ้ำบนระบบของพวกเขา
Thushi

9
@Thushi ในกรณีนี้ภาพหน้าจอเหมาะสมเพราะพวกเขาไม่สามารถวางสัญลักษณ์สัญลักษณ์หายไปได้ที่นี่
Sparhawk

คุณสามารถแก้ไขในภาพหน้าจอของคำสั่งที่รันโดยไม่ต้องใช้ส่วนท้ายgrepและผลลัพธ์ของalias grepและtype grep?
Michael Homer

คำตอบ:


28

สกรีนช็อตปรากฏขึ้นเพื่อแสดงรหัสสี ANSIที่มีการตัดคำซึ่งควบคุมการแสดงข้อความ ข้อความตัวหนา / สว่างเกิดขึ้นตามลำดับ␛[1mซึ่งโดยปกติแล้วจะถูกตีความโดยสถานีของคุณและไม่แสดงบนหน้าจอโดยตรง: มันทำให้บิตของข้อความถัดไปสดใส ภาพหน้าจอของgrepเอาต์พุตun ped แสดงความแตกต่างของสีระหว่างฉลากและค่าในแต่ละบรรทัดดังนั้นเอาต์พุตดั้งเดิมจึงใช้งานได้

ดูเหมือนว่าลำดับนั้นถูกทำลายโดยรอบสุดท้ายของคุณgrepซึ่งตรงกับ "m" ในรหัส (เนื่องจากเป็นตัวอักษร[a-z]) และพยายามเน้นสีแดงเอง ซึ่งเหลือลำดับการหลบหนีบางส่วนไว้ด้านหลังซึ่งเทอร์มินัลของคุณไม่สามารถดำเนินการได้

อักขระเลี่ยงคือ U + 001B ซึ่งเป็นเลขฐานสิบหกที่แสดงในกล่องอักขระที่ไม่รู้จัก สิ่งที่ปรากฏคือการหลบหนี (กล่อง), a [, a 1, สีแดงmตามด้วยข้อความที่ตรงกับที่คาดไว้ "eng" และเกิดขึ้นแบบเดียวกันในตอนท้ายด้วย "22" (รหัสตัวเลขสำหรับ "สีและความเข้มปกติ")


ผลลัพธ์ที่เสียหายคือ:

␛ [1 ␛ [31m meng ␛ [22m ␛ [22 ␛ [31m m ␛ [22m 

โดยที่␛[31mทำให้ข้อความเป็นสีแดงและ␛[22mเปลี่ยนเป็นสีขาวทั้งคู่แทรกโดยgrepรอบmตัวอักษรให้เป็นข้อความต้นฉบับ ต้นฉบับเป็นเพียง:

 ␛ [1m eng] ␛ [22m 

ซึ่งเพิ่งจะสว่าง " eng" จากนั้นสลับกลับเป็นข้อความปกติ

คุณสามารถตรวจสอบสิ่งนี้ได้โดยเปลี่ยนขั้นตอนสุดท้ายgrepเป็นgrep --color=alwaysและส่งไปยังhexdumpซึ่งจะแสดงอักขระที่ไม่สามารถพิมพ์ได้ทั้งหมดและตัวอักษรที่ตีความโดยเทอร์มินัลของคุณ


คุณสามารถจัดการกับเรื่องนี้ได้หลายวิธี สิ่งหนึ่งคือการใช้grepโดยไม่ใช้นามแฝงของคุณในขณะนี้:

./trans --id --input /path/to/txt | grep ISO | \grep [a-z]

แบ็กสแลชชั่วคราวจะข้ามนามแฝงและทำงานgrepโดยตรง

อีกวิธีหนึ่งคือการตัดรหัส ANSI ออกจากคำสั่งดั้งเดิมซึ่งมีคำแนะนำในคำถามนี้ :

./trans --id --input /path/to/txt | perl -pe 's/\e\[[\d;]*m//g' | grep ISO | grep [a-z]

อีกตัวเลือกหนึ่งคือการเพิ่มไปป์ที่ไม่เกี่ยวข้องในตอนท้าย:

./trans --id --input /path/to/txt | grep ISO | grep [a-z] | cat

เนื่องจากgrepผลลัพธ์สุดท้ายไม่ใช่โดยตรงไปยัง TTY แต่เพื่อcatผ่านไปป์จะไม่แทรกการเน้นสี

บางทีตัวเลือกที่ดีที่สุดคือให้ Translate Shell หยุดใช้ลำดับการควบคุมเทอร์มินัลในเอาต์พุตของตัวเองตั้งแต่แรกเมื่อไม่ได้ไปที่เทอร์มินัล สิ่งนั้นจะเกี่ยวข้องกับรายงานข้อผิดพลาดจากคุณถึงผู้เขียนและการแก้ไขรหัสในการansi()ทำงานของ Translate Shell แต่มีใครสามารถหลบมันได้บ้าง:

TERM=dumb ./trans --id --input /path/to/txt | grep ISO | grep [a-z]

สิ่งนี้จะผ่านdumbประเภทอาคารในสภาพแวดล้อมของ Translate Shell ซึ่งอย่างน้อยจะรับรู้ว่าไม่มีการรองรับสี ECMA-48 (น่าเสียดายที่ Translate Shell ไม่ได้ใช้ terminfo และเพียง แต่ hardwires ในโค้ดของตัวเองประเภทเทอร์มินัลที่เข้าใจและลำดับการควบคุมที่ใช้)


ว้าวฉันจะไม่สามารถแก้ไขข้อบกพร่องนี้ได้ด้วยตัวเองและไม่มีสถานที่เช่นนี้ดังนั้นขอบคุณ!
Freedo

IMO ผู้กระทำผิดอาจเป็นตัวแปรที่ใช้งานไม่ได้GREP_COLORหรือGREP_COLORSสภาพแวดล้อมที่มีลำดับการหลบหนี SGR ที่สมบูรณ์แทนที่จะเป็นเพียงตัวเลข
egmont

ว้าวโซลูชั่นมากมาย คุณสามารถเพิ่ม--color=nogrep สุดท้าย (หรือใช้TERM=dumbกับมัน)
Ángel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.