รู้จักกับ "โคลอน" (:) ใน Shell Script: คำสั่งที่ทำอะไรก็ไม่รู้ แต่สำคัญจนต้องใช้! 🤯

เคยไหมที่เขียนโค้ด Shell Script มาตั้งนาน แต่ก็ยังเจอเทคนิคใหม่ๆ ที่ทำให้ทึ่งได้เสมอ? สำหรับผู้เขียนบทความนี้ สิ่งที่เพิ่งค้นพบและทำให้ประหลาดใจสุดๆ คือ "โคลอน" (:) ที่อยู่ใน Shell Script นี่แหละ! ฟังดูเหมือนจะไม่มีประโยชน์อะไร แต่จริงๆ แล้วมันมีบทบาทสำคัญที่คาดไม่ถึง

ที่มาที่ไป: กาแฟที่เย็นและร้อน กับโคลอนที่ช่วยชีวิต

ในโลกที่เต็มไปด้วยเทอร์มินัลที่เปิดทิ้งไว้ และสคริปต์ที่ไม่อยากเขียน ก็มีวันหนึ่งที่กาแฟข้างๆ เย็นชืด ส่วนอีกแก้วก็ร้อนเกินไป และท่ามกลางความวุ่นวายนั้นเอง... โคลอนเพียงตัวเดียวกลับกลายเป็นฮีโร่ที่ช่วยให้งานสำเร็จลุล่วงไปได้

ตรวจสอบ Argument ที่จำเป็น: จาก 4 บรรทัด เหลือแค่ 1 บรรทัด!

เวลาเขียนสคริปต์ที่ต้องรับ Argument บางตัวเป็นสิ่งที่ต้องมี เป็นเรื่องปกติที่เราจะเขียน if-statement แบบนี้:

if [ -z "$1" ]; then
echo "Error: Argument 1 is required." >&2
exit 1
fi

แต่จะดีแค่ไหนถ้าเราสามารถย่อ 4 บรรทัดนี้ให้เหลือเพียงบรรทัดเดียว?

: "${1:?Error: Argument 1 is required.}"

สังเกตไหมว่า ถ้าเราลองอ้างถึงตัวแปรที่มีชื่อชัดเจน ผลลัพธ์จะเหมือนเดิม แต่จะระบุชื่อตัวแปรที่ผิดพลาดได้ง่ายขึ้น!

Parameter Expansion และเรื่องราวของ :?

ในตัวอย่างข้างต้น มีสองส่วนที่ทำงานอยู่ ส่วนหนึ่งคือ "Parameter Expansion" ซึ่งมีรูปแบบคือ ${name:?diagnostic}

  • การทำงาน: รูปแบบนี้จะตรวจสอบว่าตัวแปร $name ถูกตั้งค่าไว้หรือไม่ หรือมีค่าว่างเปล่าหรือไม่ ถ้าเป็นเช่นนั้น ข้อความ diagnostic จะถูกแสดงไปยัง stderr และสคริปต์จะหยุดทำงานพร้อมกับค่า exit code ที่ไม่เป็นศูนย์
  • กรณีตัวแปรถูกตั้งค่า: หากตัวแปร $name ถูกตั้งค่าไว้แล้ว มันจะทำงานเหมือนกับ $name ปกติ

แล้วโคลอนอีกตัวล่ะ?

นั่นคือโคลอนตัวแรก แต่แล้วโคลอนอีกตัวที่อยู่โดดเดี่ยวตอนต้นบรรทัดล่ะ?

: คือ Null Command หรือคำสั่งที่ไม่มีผลอะไร เป็น Built-in command ที่ทำหน้าที่เพียงประเมินค่า Argument ของมันเท่านั้น แล้วทิ้งผลลัพธ์ไป

: เป็นคำสั่งที่เก่าแก่มาก ย้อนไปถึง Thompson shell ในปี 1971 ซึ่งในตอนนั้นมันทำหน้าที่เป็นทั้งป้ายกำกับ (label) และเครื่องหมายคอมเมนต์แรกใน Unix ด้วย!

โคลอนเพิ่มเติม: ความมหัศจรรย์ที่ซ่อนอยู่

เราอาจจะพอรู้แล้วว่า : มีอะไรมากกว่าที่ตาเห็น แต่เพื่อพิสูจน์ความมหัศจรรย์ที่แท้จริงของ Null Command ลองดูการใช้งานเหล่านี้ ที่ทำให้ผู้เขียนทึ่งสุดๆ:

# ตัวอย่างการตั้งค่าตัวแปร DATA_DIR ถ้ายังไม่ได้ตั้งค่า
: "${DATA_DIR:=/var/data}"
echo "DATA_DIR is: $DATA_DIR"

ถ้าคุณชอบการพิมพ์น้อยลง (เพราะต้องไปให้เร็ว!) Null Command และ Parameter Expansion คือคู่หูที่คุ้มค่าแก่การศึกษา ก่อนที่กาแฟของคุณจะเย็นชืด

คำถามที่พบบ่อย (FAQ)

หลังจากได้อ่านบทความนี้ อาจมีบางคำถามที่ผุดขึ้นมา นี่คือคำตอบสำหรับคำถามที่พบบ่อย:

ทำไมต้องใช้ Null Command? ค่า Parameter Expansion ก็ทำงานได้ไม่ใช่หรือ?

Parameter Expansion จะทำงานอยู่แล้ว แต่ถ้าไม่มี Null Command หรือการใช้งานที่คล้ายกัน สคริปต์จะมองว่าผลลัพธ์ของ Parameter Expansion เป็น "คำสั่ง" ที่ต้องรัน ซึ่งอาจทำให้เกิดข้อผิดพลาดได้

เช่น:

% ${HELLO:=123}
zsh: command not found: 123

แต่เมื่อเราใช้ Null Command นำหน้า Parameter Expansion ผลลัพธ์จะถูกทิ้งไป แต่การประเมินค่า (การตั้งค่า HELLO เป็น 123) จะยังคงเกิดขึ้น:

% : ${HELLO:=123}
% echo $HELLO
123

ทำไมต้องใช้ Null Command เมื่อฉันสามารถใช้ VAR=${VAR:-default-value} ได้?

จริงๆ แล้วส่วนนี้ขึ้นอยู่กับความชอบส่วนบุคคล แต่การใช้ Null Command จะช่วยลดโอกาสในการพิมพ์ผิดได้ เนื่องจากเราต้องพิมพ์ชื่อตัวแปรเพียงครั้งเดียว

  • ใช้ Null Command: : "${DATADIR:=/var/data}" (DATA\DIR ถูกกล่าวถึง 1 ครั้ง)
  • แบบปกติ (อาจผิดพลาด): DATADIR="${DATADRI:-/var/data}" (สังเกต DRI ที่อาจผิด)

การทำความเข้าใจและนำเทคนิคเล็กๆ น้อยๆ เหล่านี้มาใช้ จะช่วยให้การเขียน Shell Script ของคุณมีประสิทธิภาพและน่าทึ่งยิ่งขึ้น! ✨

ขอบคุณ แหล่งข้อมูล
https://refp.se/articles/your-shell-and-the-magic-colon

รู้จักกับ "โคลอน" (:) ใน Shell Script: คำสั่งที่ทำอะไรก็ไม่รู้ แต่สำคัญจนต้องใช้! 🤯เคยไหมที่เขียนโค้ด Shell Script มาตั้งนาน แต่ก็ยังเจอเทคนิคใหม่ๆ ที่ทำให้ทึ่งได้เสมอ? สำหรับผู้เขียนบทความนี้ สิ่งที่เพิ่งค้นพบและทำให้ประหลาดใจสุดๆ คือ "โคลอน" (:) ที่อยู่ใน Shell Script นี่แหละ! ฟังดูเหมือนจะไม่มีประโยชน์อะไร แต่จริงๆ แล้วมันมีบทบาทสำคัญที่คาดไม่ถึงที่มาที่ไป: กาแฟที่เย็นและร้อน กับโคลอนที่ช่วยชีวิตในโลกที่เต็มไปด้วยเทอร์มินัลที่เปิดทิ้งไว้ และสคริปต์ที่ไม่อยากเขียน ก็มีวันหนึ่งที่กาแฟข้างๆ เย็นชืด ส่วนอีกแก้วก็ร้อนเกินไป และท่ามกลางความวุ่นวายนั้นเอง... โคลอนเพียงตัวเดียวกลับกลายเป็นฮีโร่ที่ช่วยให้งานสำเร็จลุล่วงไปได้ตรวจสอบ Argument ที่จำเป็น: จาก 4 บรรทัด เหลือแค่ 1 บรรทัด!เวลาเขียนสคริปต์ที่ต้องรับ Argument บางตัวเป็นสิ่งที่ต้องมี เป็นเรื่องปกติที่เราจะเขียน if-statement แบบนี้:if [ -z "$1" ]; then echo "Error: Argument 1 is required." >&2 exit 1 fiแต่จะดีแค่ไหนถ้าเราสามารถย่อ 4 บรรทัดนี้ให้เหลือเพียงบรรทัดเดียว?: "${1:?Error: Argument 1 is required.}"สังเกตไหมว่า ถ้าเราลองอ้างถึงตัวแปรที่มีชื่อชัดเจน ผลลัพธ์จะเหมือนเดิม แต่จะระบุชื่อตัวแปรที่ผิดพลาดได้ง่ายขึ้น!Parameter Expansion และเรื่องราวของ :?ในตัวอย่างข้างต้น มีสองส่วนที่ทำงานอยู่ ส่วนหนึ่งคือ "Parameter Expansion" ซึ่งมีรูปแบบคือ ${name:?diagnostic}การทำงาน: รูปแบบนี้จะตรวจสอบว่าตัวแปร $name ถูกตั้งค่าไว้หรือไม่ หรือมีค่าว่างเปล่าหรือไม่ ถ้าเป็นเช่นนั้น ข้อความ diagnostic จะถูกแสดงไปยัง stderr และสคริปต์จะหยุดทำงานพร้อมกับค่า exit code ที่ไม่เป็นศูนย์กรณีตัวแปรถูกตั้งค่า: หากตัวแปร $name ถูกตั้งค่าไว้แล้ว มันจะทำงานเหมือนกับ $name ปกติแล้วโคลอนอีกตัวล่ะ?นั่นคือโคลอนตัวแรก แต่แล้วโคลอนอีกตัวที่อยู่โดดเดี่ยวตอนต้นบรรทัดล่ะ?: คือ Null Command หรือคำสั่งที่ไม่มีผลอะไร เป็น Built-in command ที่ทำหน้าที่เพียงประเมินค่า Argument ของมันเท่านั้น แล้วทิ้งผลลัพธ์ไป: เป็นคำสั่งที่เก่าแก่มาก ย้อนไปถึง Thompson shell ในปี 1971 ซึ่งในตอนนั้นมันทำหน้าที่เป็นทั้งป้ายกำกับ (label) และเครื่องหมายคอมเมนต์แรกใน Unix ด้วย!โคลอนเพิ่มเติม: ความมหัศจรรย์ที่ซ่อนอยู่เราอาจจะพอรู้แล้วว่า : มีอะไรมากกว่าที่ตาเห็น แต่เพื่อพิสูจน์ความมหัศจรรย์ที่แท้จริงของ Null Command ลองดูการใช้งานเหล่านี้ ที่ทำให้ผู้เขียนทึ่งสุดๆ:# ตัวอย่างการตั้งค่าตัวแปร DATA_DIR ถ้ายังไม่ได้ตั้งค่า : "${DATA_DIR:=/var/data}" echo "DATA_DIR is: $DATA_DIR"ถ้าคุณชอบการพิมพ์น้อยลง (เพราะต้องไปให้เร็ว!) Null Command และ Parameter Expansion คือคู่หูที่คุ้มค่าแก่การศึกษา ก่อนที่กาแฟของคุณจะเย็นชืดคำถามที่พบบ่อย (FAQ)หลังจากได้อ่านบทความนี้ อาจมีบางคำถามที่ผุดขึ้นมา นี่คือคำตอบสำหรับคำถามที่พบบ่อย:ทำไมต้องใช้ Null Command? ค่า Parameter Expansion ก็ทำงานได้ไม่ใช่หรือ?Parameter Expansion จะทำงานอยู่แล้ว แต่ถ้าไม่มี Null Command หรือการใช้งานที่คล้ายกัน สคริปต์จะมองว่าผลลัพธ์ของ Parameter Expansion เป็น "คำสั่ง" ที่ต้องรัน ซึ่งอาจทำให้เกิดข้อผิดพลาดได้เช่น:% ${HELLO:=123} zsh: command not found: 123แต่เมื่อเราใช้ Null Command นำหน้า Parameter Expansion ผลลัพธ์จะถูกทิ้งไป แต่การประเมินค่า (การตั้งค่า HELLO เป็น 123) จะยังคงเกิดขึ้น:% : ${HELLO:=123} % echo $HELLO 123ทำไมต้องใช้ Null Command เมื่อฉันสามารถใช้ VAR=${VAR:-default-value} ได้?จริงๆ แล้วส่วนนี้ขึ้นอยู่กับความชอบส่วนบุคคล แต่การใช้ Null Command จะช่วยลดโอกาสในการพิมพ์ผิดได้ เนื่องจากเราต้องพิมพ์ชื่อตัวแปรเพียงครั้งเดียวใช้ Null Command: : "${DATADIR:=/var/data}" (DATA\DIR ถูกกล่าวถึง 1 ครั้ง)แบบปกติ (อาจผิดพลาด): DATADIR="${DATADRI:-/var/data}" (สังเกต DRI ที่อาจผิด)การทำความเข้าใจและนำเทคนิคเล็กๆ น้อยๆ เหล่านี้มาใช้ จะช่วยให้การเขียน Shell Script ของคุณมีประสิทธิภาพและน่าทึ่งยิ่งขึ้น! ✨https://refp.se/articles/your-shell-and-the-magic-colon
Shared content
REFP.SE
A shell colon does nothing. Use it anyway. | Filip Roséen - refp.se
I've written more shell scripts than I can count, but I still stumble upon tricks that honestly blow my mind far too often than I care to admit. Latest thing that blew my head clean off? The shell colon.
6 Comments 0 Shares 257 Views 0 Reviews