น่าแปลกที่การใช้คอมพิวเตอร์เพื่อให้มนุษย์สามารถอ่านเอาต์พุตได้นั้นไม่ใช่เรื่องง่าย ด้วยการแนะนำสตรีมมาตรฐานและเอาต์พุตมาตรฐานโดยเฉพาะ โปรแกรมจึงมีวิธีพูดคุยกันโดยใช้สตรีมข้อความธรรมดา แต่การทำให้มีมนุษยธรรมและการแสดง stdout เป็นอีกเรื่องหนึ่ง เทคโนโลยีในยุคคอมพิวเตอร์พยายามแก้ปัญหานี้มาตลอด ตั้งแต่การใช้อักขระ ASCII ในการแสดงผลของคอมพิวเตอร์วิดีโอไปจนถึงคำสั่งเชลล์สมัยใหม่ เช่น echo
และ printf
.
ความก้าวหน้าเหล่านี้ไม่ราบรื่น งานพิมพ์เอาต์พุตไปยังเทอร์มินัลนั้นเต็มไปด้วยนิสัยใจคอสำหรับโปรแกรมเมอร์ในการนำทาง ดังที่แสดงตัวอย่างโดยงานที่ไม่ซับซ้อนที่หลอกลวงในการขยายลำดับการหลบหนีเพื่อพิมพ์ขึ้นบรรทัดใหม่ การขยายตัวยึดตำแหน่ง \n
สามารถทำได้หลายวิธี โดยแต่ละแบบมีประวัติและความซับซ้อนที่แตกต่างกันไป
การใช้ echo
ตั้งแต่การปรากฏตัวใน Multics ไปจนถึงการแพร่หลายของระบบที่เหมือน Unix ในยุคปัจจุบัน echo
ยังคงเป็นเครื่องมือที่คุ้นเคยในการทำให้เทอร์มินัลของคุณพูดว่า "สวัสดีชาวโลก!" น่าเสียดาย การใช้งานที่ไม่สอดคล้องกันในระบบปฏิบัติการทำให้การใช้งานยุ่งยาก โดยที่ echo
ในบางระบบจะขยายเอสเควนซ์ซีเควนซ์โดยอัตโนมัติ บางระบบต้องการ -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
เนื่องจากความไม่สอดคล้องกันในการใช้งาน echo
ถือว่าไม่สามารถพกพาได้ นอกจากนี้ การใช้งานร่วมกับอินพุตของผู้ใช้ยังทำให้เสียหายได้ง่ายจากการโจมตีด้วยการฉีดเชลล์โดยใช้การแทนที่คำสั่ง
ในระบบที่ทันสมัย จะคงไว้เพียงเพื่อให้เข้ากันได้กับหลายโปรแกรมที่ยังคงใช้งานอยู่ ข้อกำหนด POSIX แนะนำให้ใช้ printf
ในโปรแกรมใหม่
การใช้ printf
ตั้งแต่ Unix รุ่นที่ 4 แบบพกพา printf
คำสั่งนั้นเป็น echo
ใหม่และดีกว่า . ช่วยให้คุณใช้ตัวระบุรูปแบบเพื่อป้อนข้อมูลที่มีมนุษยธรรม ในการตีความลำดับการยกเว้นแบ็กสแลช ให้ใช้ %b
. ลำดับอักขระ \n
ตรวจสอบให้แน่ใจว่าผลลัพธ์จบลงด้วยการขึ้นบรรทัดใหม่:
printf "%b\n" "Many females in Oble are \noblewomen"
# Many females in Oble are
# oblewomen
แม้ว่า printf
มีตัวเลือกเพิ่มเติมที่ทำให้แทนที่ echo
. ได้อย่างมีประสิทธิภาพยิ่งขึ้น ยูทิลิตีนี้ไม่สามารถป้องกันความผิดพลาดได้และอาจเสี่ยงต่อการถูกโจมตีด้วยสตริงรูปแบบที่ไม่สามารถควบคุมได้ สิ่งสำคัญสำหรับโปรแกรมเมอร์คือต้องจัดการข้อมูลของผู้ใช้อย่างระมัดระวัง
การขึ้นบรรทัดใหม่ในตัวแปร
ในความพยายามที่จะปรับปรุงการพกพาระหว่างคอมไพเลอร์ มาตรฐาน ANSI C ก่อตั้งขึ้นในปี 1983 ด้วยการอ้างอิง ANSI-C โดยใช้ $'...'
, ลำดับหลีกจะถูกแทนที่ในเอาต์พุตตามมาตรฐาน
ซึ่งช่วยให้เราสามารถจัดเก็บสตริงที่มีการขึ้นบรรทัดใหม่ในตัวแปรที่พิมพ์โดยมีการขึ้นบรรทัดใหม่ คุณสามารถทำได้โดยการตั้งค่าตัวแปร แล้วเรียกมันด้วย printf
โดยใช้ $
:
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
ตัวแปรที่ขยายเป็น single-quoted ซึ่งส่งผ่านอย่างแท้จริงไปยัง printf
. และเช่นเคย การจัดการอินพุตอย่างถูกต้องเป็นสิ่งสำคัญ
รอบโบนัส:การขยายพารามิเตอร์ของเชลล์
ในบทความของฉันที่อธิบาย Bash และวงเล็บปีกกา ฉันได้กล่าวถึงความมหัศจรรย์ของการขยายพารามิเตอร์เชลล์ เราสามารถใช้ส่วนขยายเดียว ${parameter@operator}
เพื่อตีความลำดับการหลบหนีด้วย เราใช้ printf
ของ %s
ตัวระบุที่จะพิมพ์เป็นสตริงและ E
โอเปอเรเตอร์จะขยายลำดับการหลบหนีในตัวแปรของเราอย่างเหมาะสม:
printf "%s\n" ${puns@E}
# umber
# arrow
# ether
# ice
ความท้าทายอย่างต่อเนื่องของการพูดคุยในมนุษย์
การแก้ไขสตริงยังคงเป็นปัญหาที่ยุ่งยากสำหรับโปรแกรมเมอร์ นอกจากการได้ภาษาและเชลล์เพื่อให้เห็นด้วยกับความหมายของตัวยึดตำแหน่งแล้ว การใช้ Escape Sequence ที่ถูกต้องยังต้องอาศัยการดูรายละเอียด
การแก้ไขสตริงที่ไม่ดีอาจนำไปสู่ผลลัพธ์ที่ดูงี่เง่า รวมทั้งทำให้เกิดช่องโหว่ด้านความปลอดภัย เช่น จากการโจมตีแบบฉีด จนกว่าวิวัฒนาการขั้นต่อไปของเทอร์มินัลจะให้เราพูดเป็นอิโมจิ เราควรให้ความสนใจเมื่อพิมพ์ผลงานสำหรับมนุษย์ให้ดีที่สุด