คุณสามารถปรับวิธีการของคุณได้เล็กน้อย แทนการไพพ์ไปที่cowsay
โดยตรงอ่านเอาต์พุตจนกว่าอักขระที่คั่น, ส่งเอาต์พุตนั้นไปยังcowsay
จากนั้นพิมพ์อักขระนั้นหลังจากทุกคำสั่ง:
exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
PROMPT_COMMAND='printf "\0"'
ที่นี่ฉันใช้อักขระ ASCII NUL คุณสามารถใช้อย่างอื่นที่ไม่น่าจะปรากฏในเอาท์พุทคำสั่ง
สิ่งนี้จะพิมพ์หลังจากพรอมต์ดังนั้นผลลัพธ์จะน่าเกลียด:
$ export LC_ALL=C
$ exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
$ PROMPT_COMMAND='printf "\0"'
$ ls
$
______________________________________
/ Desktop Documents Downloads Music \
| Pictures Public Templates Videos
\ examples.desktop /
--------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$ echo foo
$
______
< foo >
------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
โปรดทราบว่าสิ่งนี้จะทำลายคำสั่งใด ๆ ที่พยายามใช้งานเอาต์พุตที่ซับซ้อนหรือมีส่วนต่อประสานกับผู้ใช้ข้อความ (คิดว่าตัวแก้ไขบรรทัดคำสั่งเพจเจอร์ ฯลฯ )
สมมติว่าคุณรู้อยู่แล้วว่าสิ่งexec > >(...)
ใดมีส่วนในกระบวนการทดแทนคือ:
while IFS= read -d '' -r line; do ... done
: นี่เป็นสำนวนที่พบบ่อยพอสมควรสำหรับการอ่านข้อมูลที่คั่นด้วยอักขระ ASCII NUL:
IFS=
ตั้งค่า IFS เป็นสตริงว่างซึ่งปิดใช้งานการแยกฟิลด์
-r
ป้องกันread
จากการปฏิบัติ\
ในการป้อนข้อมูลเป็นพิเศษ ( \n
เช่นเช่นอ่าน\n
และไม่แปลงเป็นอักขระขึ้นบรรทัดใหม่)
-d ''
เป็นวิธีที่จะบอกread
ให้อ่านจนกระทั่งอักขระ NUL
ดังนั้นสิ่งทั้งหมดจึงวนซ้ำไปยังอินพุตในส่วนที่คั่นด้วย NUL ในขณะที่รักษาเนื้อหาของอินพุตให้มากที่สุด
if [[ -n $line ]]; then ... fi; done
- ทำเฉพาะเมื่ออินพุตที่อ่านจนถึงตอนนี้ไม่ว่างเปล่า
echo; printf "%s\n" "$line" | cowsay;
- พิมพ์บรรทัดว่างนำหน้าเพื่อให้เอาต์พุต cowsay ไม่ขัดแย้งกับพรอมต์จากนั้นส่งอินพุตที่อ่านจนถึง cowsay มีความน่าเชื่อถือมากขึ้นและปลอดภัยกว่าprintf
echo
-n
แฟล็กถึงcowsay
มีประโยชน์ มันทำให้มันรักษาช่องว่าง