เทคนิคการเขียน Shell Script #1

เมื่อต้องการเขียน Shell Script เพื่อรับ Argument และ Option เช่น เขียน myscript.sh ซึ่งแบ่งเป็น 3 แบบ
1) $ sh myscript1.sh myfirstname mylastname 16
2) $ sh myscript2.sh -f myfirstname -l mylastname -a 16
3) $ sh myscript3.sh –firstname myfirstname –lastname mylastname –age 16

[บทความนี้ ใช้งานบน Ubuntu 12.04 Server และ ใช้ Bash Shell]

1) วิธีแรก คือ การรับตัว Argument เรียงตามลำดับ โดยใช้ เครื่องหมาย $ ตามด้วยลำดับของตัวแปร เช่น $1, $2, $3 ดัง Script myscript1.sh มีรายละเอียด ต่อไปนี้

firstname=$1
lastname=$2
age=$3
echo "Firstname=$firstname"
echo "lastname=$lastname"
echo "age=$age"

วิธีนี้ ข้อดีคือ สร้างง่าย แต่ ข้อเสียคือ ต้องใส่ Argument ตามลำดับเท่านั้น

2) วิธีที่สอง คือ มีการใช้ Option แบบชื่อสั้น เช่น -f, -l ,-a โดยต้องใช้คำสั่ง getopts ดังตัวอย่าง Script myscript2.sh

getopts "f:l:a:" opt
while [ "$opt" != "?" ]
do
   case $opt in
    f)
     echo "Firstname: $OPTARG"
     ;;
    l)
     echo "Lastname: $OPTARG"
     ;;
    a)
     echo "Age: $OPTARG"
     ;;
    esac
 getopts "f:l:a:" opt
done

อธิบายเพิ่มเติม

  • getopts "f:l:a:" opt
    คำสั่งนี้ บอกว่า getopts จะรับ Option คือ f, l และ a และ เมื่อรับมาแล้ว จะใส่ในตัวแปร opt
    ส่วนใน “f:l:a:” นั้น เป็นการกำหนด Short Option Name โดยที่ เป็นอักษรตัวเดียว และ ค่า Option ใด ไม่มี เครื่องหมาย “:” แสดงว่า ไม่ต้องการใส่ค่า
    Option ใด มี     เครื่องหมาย “:” แสดงว่า ต้องการมีการใส่ค่า
    Option ใด ไม่มี เครื่องหมาย “::” แสดงว่า จะใส่ค่า หรือไม่ใส่ค่า ก็ได้
  • while [ "$opt" != "?" ] … done
    วนลูป ทุก Options จนเจอค่า “?” จึงหยุดทำงาน
  • case $opt in … esac
    เป็นการ Switch Case ตัว Option ที่เข้ามา ระหว่าง f, l และ a ให้ทำงานตามสั่ง
  • $OPTARG
    เป็นค่าที่ให้มา ผ่าน Option นั้นๆ เช่น หากมีการสั่งงานด้วยคำสั่ง

    sh myscript2.sh -f Somchai -l Jaidee -a 16
    เมื่อลูป ค่า $opt เป็น l , ก็จะได้ค่า $OPTARG เป็น Somchai เป็นต้น

วิธีนี้ มีข้อดีคือ ง่ายต่อการพัฒนา สามารถ สลับตำแหน่งของ Option ได้ดีกว่าวิธีแรก แต่มีข้อเสียคือ ชื่อย่อ ของ Option นั้นสั้น อาจจะทำให้ยากต่อการสื่อสาร

3) วิธีที่สาม คือ มีการใช้งาน Option แบบชื่อยาว เช่น –firstname, –lastname, –age
ตัวอย่าง

if ! options=$(getopt -o f:l:a: -l firstname:,lastname:,age: -- "$@")
then
 exit 1
fi

set -- $options

while [ $# -gt 0 ]
do
 case $1 in
   -f|--firstname) echo "Firstname: $2" ; shift 2;;
   -l|--lastname) echo "Lastname : $2"; shift 2 ;;
   -a|--age) echo "Age: $2" ; shift 2 ;;
   --) shift ; break;;
 esac
done

ทั้งนี้ สิ่งที่แตกต่างระหว่างวิธีที่ 2) และ 3) คือ การใช้งาน “getopts” นั้น จะไม่สามารถใส่ Long Options ได้ ต้องใช้ “getopt” จึงจะใช้งานได้ นอกนั้น ก็คล้ายๆกันครับ