Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

วิธีพิมพ์บรรทัดใหม่ในเอาต์พุตบรรทัดคำสั่ง

น่าแปลกที่การใช้คอมพิวเตอร์เพื่อให้มนุษย์สามารถอ่านเอาต์พุตได้นั้นไม่ใช่เรื่องง่าย ด้วยการแนะนำสตรีมมาตรฐานและเอาต์พุตมาตรฐานโดยเฉพาะ โปรแกรมจึงมีวิธีพูดคุยกันโดยใช้สตรีมข้อความธรรมดา แต่การทำให้มีมนุษยธรรมและการแสดง 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 ที่ถูกต้องยังต้องอาศัยการดูรายละเอียด

การแก้ไขสตริงที่ไม่ดีอาจนำไปสู่ผลลัพธ์ที่ดูงี่เง่า รวมทั้งทำให้เกิดช่องโหว่ด้านความปลอดภัย เช่น จากการโจมตีแบบฉีด จนกว่าวิวัฒนาการขั้นต่อไปของเทอร์มินัลจะให้เราพูดเป็นอิโมจิ เราควรให้ความสนใจเมื่อพิมพ์ผลงานสำหรับมนุษย์ให้ดีที่สุด