ที่มาที่ไป
ต้องเล่าย้อนหลังไปถึงตอนที่เรากำลังพิมพ์คำสั่ง เพื่อสั่งให้ Linux ทำงานอะไรบ้างอย่างให้เราผ่าน Terminal และหลังจากที่เราเคาะ Enter คำสั่งเหล่านั้นก็จะถูกส่งมาผ่านยัง Shell ซึ่ง ในบทความนี้ ทุกครั้งที่เราเอ่ยถึง Shell เราจะหมายถึง Bash - Bourne Again SHell จากนั้นเมื่อ Shell รับชุดคำสั่งมา ก็จะเปิดกลไกการทำงานที่เรียกว่า Shell Operation ที่จะมีขั้นตอนย่อยหลายขั้นตอน ซึ่งหนึ่งในขั้นตอนจะเรียกว่า Shell Expansion ใน Shell Expansion ยังมีขั้นตอนย่อย ๆ อีกหลายขั้นตอน และหนึ่งในขั้นตอนย่อยใน Shell Expansion ก็คือ Word Splitting ที่เรากำลังจะพูดถึง
Word Splitting ทำอะไร
เวลาที่ Shell เห็นประโยค (กลุ่มของคำที่เรียงร้อยกัน) ที่เกิดจากการทำงานของ Shell Expansion Shell จะทำการแยกคำในประโยค ตามตัวคั่น (delimiter) ที่ถูกกำหนดไว้ด้วยตัวแปร IFS (Internal Field Separator) โดยค่า default ของ IFS จะประกอบด้วยช่องว่าง ( ), แท็บ (\t), และบรรทัดใหม่ (\n) ซึ่งหมายความว่า Bash จะใช้ตัวแบ่งเหล่านี้ในการแยกข้อความออกเป็นคำ เช่น “This is a filename” เมื่อเกิดการทำ Word Splitting ก็จะถูกเปลี่ยนเป็น This, is, a, filename ทั้งหมด 4 คำ ดังนั้น
ถ้า “This is a filename” ไม่เกิดการทำ Word Splitting เมื่อเรียกใช้คำสั่ง touch คำสั่งจะเห็นว่ามี argument เพียงตัวเดียว ที่เป็นประโยค การทำงานของคำสั่ง touch ก็จะคิดว่า ต้องทำงานกับไฟล์เดียวที่ชื่อว่า ‘This is a filename’
~/word_splitting ❯ touch "This is a filename" ~/word_splitting ❯ ls -la total 8 drwxrwxr-x 2 drs drs 4096 Oct 5 22:56 . drwxr-x--- 9 drs drs 4096 Oct 5 22:56 .. -rw-rw-r-- 1 drs drs 0 Oct 5 22:56 'This is a filename'
ถ้า “This is a filename” ไม่เกิดการทำ Word Splitting เมื่อเรียกใช้คำสั่ง touch คำสั่งก็จะเห็นว่า มี argument ทั้งหมด 4 ตัว ดั้งนั้น การทำงานของคำสั่ง touch ก็จะคิดว่า ต้องทำงานกับทั้ง 4 ไฟล์ เมื่อไม่มี 4 ไฟล์ ก็จะสร้างไฟล์ขนาด 0 byte ขึ้นมาทั้งหมด 4 ไฟล์
~/word_splitting ❯ filename="This is a filename" ~/word_splitting ❯ touch $filename ~/word_splitting ❯ ls -la total 8 drwxrwxr-x 2 drs drs 4096 Oct 5 23:01 . drwxr-x--- 9 drs drs 4096 Oct 5 22:56 .. -rw-rw-r-- 1 drs drs 0 Oct 5 23:01 This -rw-rw-r-- 1 drs drs 0 Oct 5 23:01 a -rw-rw-r-- 1 drs drs 0 Oct 5 23:01 filename -rw-rw-r-- 1 drs drs 0 Oct 5 23:01 is
แล้ว Word Splitting จะทำงานเมื่อไหร่
Word Splitting จะทำงานก็ต่อเมื่อ ประโยคนั้นเกิดจากการทำ Expansion ในการขั้นตอนของ Shell Expansion หรือ ถ้าจะพูดในทางตรงกันขึ้นก็คือ ถ้าประโยคนั้นไม่ได้เกิดจากขั้นตอนการ Expansion ก็จะไม่มีการทำ Word Splitting
และนี่ก็คือสาเหตุที่ผลการเรียกคำสั่ง touch “This is a filename” และ filename=”This is a filename”;touch $filename ได้ผลออกมาต่างกัน
เปลี่ยนตัวคั่นตามใจเรา
จากที่เกริ่นว่า Word Splitting จะแยกคำในประโยคตามตัวแปร IFS … แล้วถ้าประโยคของเราคั่นคำต่าง ๆ เช่น เครื่องหมาย - (dash) ต้องทำอย่างไร
ในกรณีที่ประโยคของเราคั่นคำด้วยเครื่องหมาย - เช่น “This-is-a-filename”
~/word_splitting ❯ filename="This-is-a-filename" ~/word_splitting ❯ touch $filename ~/word_splitting ❯ ls This-is-a-filename ~/word_splitting ❯ rm -f This-is-a-filename ~/word_splitting ❯ IFS="-" ~/word_splitting ❯ touch $filename ~/word_splitting ❯ ls -la total 8 drwxrwxr-x 2 drs drs 4096 Oct 5 23:29 . drwxr-x--- 9 drs drs 4096 Oct 5 22:56 .. -rw-rw-r-- 1 drs drs 0 Oct 5 23:29 This -rw-rw-r-- 1 drs drs 0 Oct 5 23:29 a -rw-rw-r-- 1 drs drs 0 Oct 5 23:29 filename -rw-rw-r-- 1 drs drs 0 Oct 5 23:29 is
end of document