"Dash" เชลล์มาตรฐานของ Ubuntu คืออะไร? คู่มือการใช้งานและความแตกต่างจาก Bash
หากคุณใช้ Ubuntu คุณอาจเคยได้ยินคำว่า Dash (dash) โดยเฉพาะอย่างยิ่งเมื่อเขียนสคริปต์เชลล์ การมีอยู่ของ Dash นี้มีความสำคัญมาก เชลล์ที่ผู้ใช้ส่วนใหญ่ใช้ในชีวิตประจำวันคือ Bash แต่เบื้องหลังระบบของ Ubuntu นั้น Dash กำลังทำงานอยู่อย่างแข็งขัน ในบทความนี้ เราจะอธิบายตั้งแต่ตำแหน่งของ Dash ซึ่งเป็น เชลล์มาตรฐานของ Ubuntu ไปจนถึง วิธีใช้งาน พื้นฐาน และความแตกต่างจาก Bash ที่หลายคนมักสับสน ในรูปแบบที่เข้าใจง่ายสำหรับผู้เริ่มต้น
สำหรับนักสร้างสรรค์เว็บ โอกาสที่จะได้สัมผัสกับสคริปต์เชลล์ในการตั้งค่าเซิร์ฟเวอร์และงานปรับใช้มีเพิ่มมากขึ้น โค้ดในบทความนี้ทั้งหมดถูกสร้างขึ้นเพื่อให้ทำงานได้เพียงแค่คัดลอกและวาง ดังนั้นโปรดลองลงมือทำและสัมผัสกับความสนุกที่ "มันทำงานได้"!
Dash คืออะไรกันแน่? และทำไมถึงใช้ใน Ubuntu?
Dash (Debian Almquist shell) เป็นหนึ่งในเชลล์บรรทัดคำสั่งที่ใช้ในระบบปฏิบัติการตระกูล UNIX คุณสมบัติที่ใหญ่ที่สุดคือ ทำงานได้เบาและรวดเร็ว เมื่อเทียบกับ Bash ซึ่งเป็นเชลล์ที่มีฟังก์ชันการทำงานสูงและมีคุณสมบัติมากมาย Dash จะเน้นไปที่ฟังก์ชันพื้นฐาน ทำให้ความเร็วในการรันสคริปต์นั้นเร็วกว่ามาก
ใน Ubuntu (และ Debian ซึ่งเป็นพื้นฐาน) ได้นำความเร็วนี้มาใช้ประโยชน์โดยเลือกใช้ Dash เป็นเชลล์ระบบเริ่มต้น (/bin/sh) สำหรับการรันสคริปต์ตอนเปิดเครื่องและการประมวลผลเบื้องหลังต่างๆ นั่นหมายความว่า นอกจากล็อกอินเชลล์ (/bin/bash) ที่เราใช้โต้ตอบในเทอร์มินัลเป็นประจำแล้ว ภายในระบบ Dash ยังทำงานจัดการงานต่างๆ ได้อย่างมีประสิทธิภาพอีกด้วย การแบ่งงานกันทำแบบ "Dash สำหรับเชลล์ระบบ, Bash สำหรับล็อกอินเชลล์" นี้เองที่สนับสนุน การทำงานที่คล่องแคล่วของ Ubuntu
ลองตรวจสอบดูว่า /bin/sh ในสภาพแวดล้อมของคุณลิงก์ไปยังอะไร เมื่อรันคำสั่งต่อไปนี้ จะแสดงตัวตนที่แท้จริงของมัน
ls -l /bin/sh
ในกรณีส่วนใหญ่ จะแสดงผลเป็น /bin/sh -> dash ซึ่งหมายความว่าตัวตนที่แท้จริงของ /bin/sh คือ Dash
วิธีใช้งาน Dash เบื้องต้น
ต่อไป เรามาลองรันสคริปต์ง่ายๆ โดยใช้ Dash กันดีกว่า วิธีใช้งาน Dash นั้นง่ายมาก
1. การสร้างไฟล์สคริปต์
ขั้นแรก สร้างไฟล์สคริปต์ง่ายๆ ด้วยโปรแกรมแก้ไขข้อความ ในที่นี้เราจะตั้งชื่อว่า hello_dash.sh
nano hello_dash.sh
เมื่อโปรแกรมแก้ไขข้อความเปิดขึ้นมา ให้คัดลอกเนื้อหาต่อไปนี้ไปวางแล้วบันทึก
#!/bin/sh
# บรรทัดข้างบนเรียกว่า "shebang" (ชีแบง) ซึ่งระบุให้รันสคริปต์นี้ด้วย /bin/sh (นั่นคือ Dash)
echo "Hello, Dash!"
2. การให้สิทธิ์ในการรัน (Execute Permission)
ให้สิทธิ์ในการรันกับไฟล์สคริปต์ที่เราเพิ่งสร้างขึ้น
chmod +x hello_dash.sh
3. การรันสคริปต์
เมื่อเตรียมการพร้อมแล้ว ก็มารันสคริปต์กันเลย
./hello_dash.sh
หากเทอร์มินัลแสดงข้อความ "Hello, Dash!" ก็ถือว่าสำเร็จ! นี่คือวิธีการรันสคริปต์ Dash ที่พื้นฐานที่สุด การระบุ #!/bin/sh ใน shebang ทำให้สคริปต์นี้ถูกตีความและรันโดย Dash
ตัวอย่างประยุกต์: ลองใช้ตัวแปรและลูปใน Dash
สำหรับตัวอย่างที่ใช้งานได้จริงมากขึ้น ลองมาดูสคริปต์ที่ใช้ตัวแปรและลูป while กัน ไวยากรณ์พื้นฐานจะคล้ายกับ Bash แต่สิ่งสำคัญคือต้องใส่ใจกับการเขียนแบบที่เข้ากันได้กับ POSIX ซึ่งจะทำงานได้อย่างแน่นอนใน Dash
สคริปต์ต่อไปนี้จะวนลูปจนกว่าตัวนับจะถึง 3 และแสดงค่าการนับปัจจุบัน
#!/bin/sh
# กำหนดตัวแปร
COUNT=1
# วนลูปต่อไปตราบใดที่ COUNT น้อยกว่าหรือเท่ากับ 3
while [ "$COUNT" -le 3 ]; do
echo "ค่าปัจจุบัน: $COUNT"
# เพิ่มค่า COUNT ไป 1 การใช้คำสั่ง expr เป็นวิธีที่แน่นอนที่สุด
COUNT=$(expr "$COUNT" + 1)
done
echo "จบการทำงานของลูป"
ลองบันทึกสคริปต์นี้ในชื่อเช่น loop_test.sh แล้วให้สิทธิ์ในการรันเช่นเดียวกัน จากนั้นรันด้วย ./loop_test.sh คุณจะเห็นการนับเลขจาก 1 ถึง 3 แสดงขึ้นมา
[ "$COUNT" -le 3 ]: นี่คือการตรวจสอบเงื่อนไข-leหมายถึง "น้อยกว่าหรือเท่ากับ" (less than or equal to) เนื่องจาก[[ ... ]]ที่ใช้บ่อยใน Bash ไม่สามารถใช้ใน Dash ได้ เราจึงควรใช้[ ... ]แทนCOUNT=$(expr "$COUNT" + 1): นี่คือการคำนวณค่าตัวแปร ใน Bash สามารถเขียนแบบง่ายๆ อย่าง((COUNT++))ได้ แต่ใน Dash การใช้คำสั่งexprเป็นวิธีที่แน่นอนและเข้ากันได้ดีที่สุด
ข้อควรระวัง: ความไม่เข้ากันระหว่าง Dash และ Bash
สิ่งที่ผู้เริ่มต้นมักจะติดขัดมากที่สุดในการเขียนสคริปต์เชลล์คือ ความแตกต่างด้านฟังก์ชันการทำงานระหว่าง Dash และ Bash กรณีที่คำสั่งที่ทำงานได้ดีในเทอร์มินัลปกติ (Bash) กลับเกิดข้อผิดพลาดในสคริปต์ที่ระบุ /bin/sh (Dash) นั้นเกิดขึ้นบ่อยครั้ง
ในสายงานการผลิตเว็บ แม้แต่การรันสคริปต์เป็น cron job บนเซิร์ฟเวอร์ หรือการรันสคริปต์จากเครื่องมือปรับใช้ ก็มักจะถูกรันด้วย Dash ซึ่งเป็นเชลล์เริ่มต้นของระบบ ดังนั้น หากเราเผลอใช้ฟังก์ชันที่ใช้ได้เฉพาะใน Bash (เรียกว่า Bashism) ไปโดยไม่รู้ตัว ก็จะกลายเป็นสาเหตุของข้อผิดพลาดที่จะเกิดขึ้นเฉพาะในสภาพแวดล้อมการใช้งานจริงเท่านั้น
ด้านล่างนี้คือตัวอย่างความไม่เข้ากันที่ควรระวังเป็นพิเศษ
1. ไม่สามารถใช้อาร์เรย์ (Array) ได้
ใน Bash เราสามารถจัดการอาร์เรย์ได้อย่างง่ายดายเช่น fruits=("Apple" "Banana" "Cherry") แต่ Dash ไม่รองรับอาร์เรย์
ตัวอย่างที่ทำงานได้เฉพาะใน Bash (เกิดข้อผิดพลาดใน Dash):
#!/bin/bash
# สังเกตว่า shebang คือ /bin/bash
fruits=("Apple" "Banana" "Cherry")
echo "ผลไม้ชนิดแรกคือ ${fruits[0]}"
2. ไม่สามารถใช้ Brace Expansion {..} ได้
ใน Bash ถ้าเขียน echo file{1..3}.txt จะขยายเป็น file1.txt file2.txt file3.txt แต่ Dash ไม่มีฟังก์ชันนี้
ตัวอย่างที่ทำงานได้เฉพาะใน Bash (แสดงผลตามที่เขียนใน Dash):
#!/bin/bash
# คำสั่งนี้จะสร้างชื่อไฟล์ 3 ชื่อใน Bash
touch data_{a,b,c}.csv
หากต้องการทำสิ่งเดียวกันใน Dash จำเป็นต้องใช้ลูป for หรือวิธีอื่นแทน
3. ไม่สามารถใช้คำสั่งทดสอบ `[[ ... ]]` ได้
ดังที่ได้กล่าวไปแล้ว คำสั่งทดสอบแบบขยายของ Bash คือ [[ ... ]] นั้นมีฟังก์ชันการทำงานสูงกว่า แต่ไม่สามารถใช้ใน Dash ได้ เราควรใช้ [ ... ] ที่เข้ากันได้กับ POSIX แทน
ตัวอย่างที่ทำงานได้เฉพาะใน Bash (เกิดข้อผิดพลาดใน Dash):
#!/bin/bash
NAME="hoge"
# [[ ... ]] สามารถใช้ && หรือ || ภายในได้
if [[ "$NAME" == "hoge" && -n "$NAME" ]]; then
echo "ชื่อคือ hoge"
fi
โค้ดทางเลือกที่ทำงานได้ใน Dash:
#!/bin/sh
NAME="hoge"
# ใน [ ... ] จะใช้ -a (AND)
if [ "$NAME" = "hoge" -a -n "$NAME" ]; then
echo "ชื่อคือ hoge"
fi
โปรดสังเกตด้วยว่าการเปรียบเทียบสตริงใช้ = แทนที่จะเป็น ==
สรุป: เขียนสคริปต์ที่แข็งแกร่งโดยคำนึงถึง Dash
ในครั้งนี้ เราได้อธิบายเกี่ยวกับ Dash ซึ่งเป็นเชลล์มาตรฐานของ Ubuntu ทั้งบทบาท หน้าที่ วิธีการใช้งานพื้นฐาน และความแตกต่างจาก Bash
- Dash มีน้ำหนักเบาและรวดเร็ว จึงถูกใช้เป็นเชลล์ระบบของ Ubuntu (
/bin/sh) - ล็อกอินเชลล์ที่เราใช้เป็นประจำคือ Bash ซึ่งมีความแตกต่างด้านฟังก์ชันการทำงาน
- เมื่อเขียนสคริiptเชลล์ ควรเขียน
#!/bin/shและพยายามเขียนตามมาตรฐาน POSIX ที่ทำงานได้ใน Dash เพื่อให้ได้สคริปต์ที่แข็งแกร่งและไม่ขึ้นอยู่กับสภาพแวดล้อม - ควรระวังไม่ใช้ฟังก์ชันเฉพาะของ Bash (Bashism) เช่น อาร์เรย์, Brace Expansion,
[[ ... ]]ในสคริปต์/bin/sh
ในช่วงแรกอาจจะสับสน แต่ถ้าเข้าใจความแตกต่างนี้แล้ว จะสามารถป้องกันปัญหาเช่น "ทำงานได้บนเครื่องโลคัล แต่ไม่ทำงานบนเซิร์ฟเวอร์" ได้ล่วงหน้า มาทำความคุ้นเคยกับโลกของ Ubuntu dash และมุ่งมั่นสร้างสคริปต์เชลล์ที่น่าเชื่อถือยิ่งขึ้นกันเถอะ!
บทความที่เกี่ยวข้อง
หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับการเขียนสคริปต์อย่างละเอียดและความเข้ากันได้กับ Bash ขอแนะนำบทความนี้ด้วย