เรื่องน่าประหลาด: ทำให้คอมพิวเตอร์แสดง Output ที่มนุษย์อ่านง่าย — ไม่ใช่เรื่องง่ายเลย ด้วย Standard Streams และ Stdout โปรแกรมสื่อสารกันด้วย Text Streams แตการ "Humanize" และแสดง Stdout นั้นเป็นอีกเรื่อง
ตั้งแต่ ASCII บนจอ Video ไปจนถึง Shell Commands สมัยใหม่อย่าง echo และ printf — ทุกอย่างพยายามแก้ปัญหานี้ แต่ยังมี "Quirks" เหลืออยู่ ตัวอย่างชัดเจน: การขยาย Escape Sequence \n เพื่อพิมพ์ Newline — ทำได้หลายวิธี แต่ละวิธีมีประวัติและข้อซับซ้อนเฉพาะตัว
ใช้ echo
ตั้งแต่ Multics ถึง Unix-like สมัยใหม่ echo เป็นเครื่องมือคุ้นเคยสำหรับ "Hello world!" แต่ Implementation ไม่สม่ำเสมอข้าม OS:
- บางระบบ:
echoขยาย Escape Sequences อัตโนมัติ - บางระบบ: ต้องใช้
-eถึงจะขยาย
echo "the study of European nerves is \neurology"
# the study of European nerves is \neurology (ไม่ขยาย)
echo -e "the study of European nerves is \neurology"
# the study of European nerves is
# eurology (ขยายได้)
เพราะ Inconsistencies นี้ → echo ถือว่า Non-portable นอกจากนี้ยังอ่อนไหวต่อ Shell Injection ผ่าน Command Substitution
ระบบสมัยใหม่เก็บ echo ไว้เพื่อ Backward Compatibility — POSIX แนะนำให้ใช้ printf ในโปรแกรมใหม่
ใช้ printf
ตั้งแต่ Unix 4th Edition printf เป็น Portable และดียกว่า echo ใช้ Format Specifiers จัดรูปแบบ Output
ตีความ Backslash Escapes: ใช้ %b — \n ให้นิ่งบรรทัดใหม่ท้าย:
printf "%b\n" "Many females in Oble are \noblewomen"
# Many females in Oble are
# oblewomen
printf มี Options เพิ่มเติมมาก — แทนที่ echo ได้สมบูรณ์ แต่ก็ยังมีช่องโหว่ Uncontrolled Format String Attack — ต้องจัดการ User Input อย่างระมัดระวัง
เก็บ Newlines ใน Variables
ANSI C Standard (1983) เพื่อ Portability ระหว่าง Compilers — ANSI-C Quoting $'...' ขยาย Escape Sequences ใน Output ตามมาตรฐาน
เก็บสตริงที่มี Newlines ใน Variable แล้วพิมพ์ด้วย Newlines จริง:
puns=$'\number\narrow\nether\nice'
printf "%b\n" "These words started with n but don't make $puns"
# These words started with n but don't make
# umber
# arrow
# ether
# ice
Variable ที่ขยายแล้วถูก Single-quote → ส่งต่อให้ printf ตรงๆ จัดการ Input ให้ดีเสมอ
โบนัส: Shell Parameter Expansion
ในบทความ Bash และ Braces เคยครอบคลุม Shell Parameter Expansion — Expansion หนึ่งคือ ${parameter@operator} สำหรับขยาย Escape Sequences
ใช้ printf กับ %s (Print as String) และ Operator E จะขยาย Escape Sequences ใน Variable:
printf "%s\n" ${puns@E}
# umber
# arrow
# ether
# ice
ความท้าทายที่ต่อเนื่อง: "พูดภาษามนุษย์"
String Interpolation ยังเป็นปัญหายากสำหรับ Programmers — นอกจากภาษา/Shell ไม่ตกลงกันใน Placeholders การ Escape ถูกต้องต้องการรายละเอียด
Interpolation ผิด → Output ดูขี้เหล็ก และอาจเปิดโอกาส Security Vulnerabilities (Injection Attacks) จนกว่า Terminal รุ่นต่อไปจะให้พูด Emoji ได้ — เราต้องระมัดระวังตอนพิมพ์ Output ให้มนุษย์อ่าน