การเขียนโปรแกรมเชลล์ (7)
เราสามารถทำการตรวจสอบเงื่อนไขในเชลล์ได้ โดยการใช้คำสั่ง "test" โดยที่ถ้าเงื่อนไขที่ทำการตรวจสอบนั้นเป็นเงื่อนไขที่ถูกต้องโปรแกรม test จะทำการให้ค่า
return code เป็น 0 แต่ถ้าเป็นเงื่อนไขที่ไม่ถูกต้องจะให้ค่าที่ไม่เป็น 0 (โดยปกติจะเป็นค่า 1)
การตรวจสอบเงื่อนไขที่เกี่ยวกับไฟล์
-r pathname | : ถูกต้องถ้ามีไฟล์อยู่และอนุญาตให้สามารถอ่านไฟล์ได้ (readable) |
-w pathname | : ถูกต้องถ้ามีไฟล์อยู่และอนุญาตให้สามารถเขียนไฟล์ได้ (writable) |
-x pathname | : ถูกต้องถ้ามีไฟล์อยู่และอนุญาตให้สามารถทำงานได้ (executable) |
-f pathname | : ถูกต้องถ้ามีไฟล์อยู่และไฟล์เป็นแบบไฟล์ธรรมดา (ordinary) |
-d pathname | : ถูกต้องถ้ามีไฟล์อยู่และไฟล์เป็นแบบไดเรกทอรี |
-c pathname | : ถูกต้องถ้ามีไฟล์อยู่และเป็นไฟล์แบบดีไวซ์ชนิด character |
-b pathname | : ถูกต้องถ้ามีไฟล์อยู่และเป็นไฟล์แบบดีไวซ์ชนิด binary |
-p pathname | : ถูกต้องถ้ามีไฟล์อยู่และเป็นไฟล์ชนิด pipe |
-u pathname | : ถูกต้องถ้ามีไฟล์อยู่และ setuid bit ถูกเซ็ต |
-g pathname | : ถูกต้องถ้ามีไฟล์อยู่และ getgid bit ถูกเซ็ต |
-k pathname | : ถูกต้องถ้า sticky bit ถูกเซ็ต |
-s pathname | : ถูกต้องถ้ามีไฟล์อยู่และเป็นไฟล์ที่มีข้อมูล |
-t channelno | : ถูกต้องถ้าเป็นไฟล์ที่ติดต่อกับ terminal (tty) |
การตรวจสอบเงื่อนไขที่เกี่ยวกับสตริง
-z string | : ถูกต้องถ้าสตริงมีความยาวเป็นศูนย์ |
-n string | : ถูกต้องถ้าสตริงมีความยาวไม่เป็นศูนย์ |
str1 = str2 | : ถูกต้องถ้าสตริงทั้งสองเหมือนกัน |
str | : ถูกต้องถ้าสตริงมีข้อมูลอยู่ (ไม่เป็น null) |
การตรวจสอบเงื่อนไขที่เกี่ยวกับตัวเลข
n1 -eq n2 | : ถูกต้องถ้า n1 เท่ากับ n2 |
n1 -ne n2 | : ถูกต้องถ้า n1 ไม่เท่ากับ n2 |
n1 -gt n2 | : ถูกต้องถ้า n1 มากกว่า n2 |
n1 -lt n2 | : ถูกต้องถ้า n1 น้อยกว่า n2 |
n1 -ge n2 | : ถูกต้องถ้า n1 มากกว่าหรือเท่ากับ n2 |
n1 -le n2 | : ถูกต้องถ้า n1 น้อยกว่าหรือเท่ากับ n2 |
การรวมเงื่อนไข
! | : เปลี่ยนผลลัพธ์เงื่อนไขเป็นตรงกันข้าม |
-o | : เงื่อนไขแบบหรือ (OR) |
-a | : เงื่อนไขแบบและ (AND) |
(...) | : รวมคำสั่ง test |
ตารางผลลัพธ์คณิตศาสตร์ลอจิกของ A กับ B
A | B | A and B | A or B |
T | T | T | T |
T | F | F | T |
F | T | F | T |
F | F | F | F |
ในการใช้คำสั่ง test กับเงื่อนไข เมื่อคำสั่ง test ตรวจสอบเงื่อนไขนั้นว่าถูกต้องก็จะทำการคืนค่า exit code 0 ให้ จากหัวข้อที่แล้ว เราได้เรียนรู้ว่าหากต้องการจะตรวจสอบค่า exit code ของโปรแกรมหรือเชลล์เราสามารถตรวจสอบจากตัวแปร "$?"
ได้ ซึ่งในที่นี้เราก็จะทำการพิมพ์ค่า exit code นั้นออกมาโดยการใช้คำสั่ง echo
ตัวอย่าง
ตัวอย่างนี้จะทดสอบว่า "/bin" เป็นไดเรกทอรีหรือไม่ ซึ่งก็จะได้ exit code
จากคำสั่ง test เป็น 0 ซึ่งก็คือ "/bin" เป็นไดเรกทอรีจริง ส่วนตัวอย่างถัดไปจะทำการตรวจสอบว่า "/bin" เป็นไฟล์หรือไม่ ซึ่งผลลัพธ์ที่ได้ก็จะเป็นเท็จ
$ test -d /bin; echo $?
0
$ test -f /bin; echo $?
1
ตัวอย่างถัดมาจะใช้เครื่องหมายก้ามปู "[...]" ทำการครอบเงื่อนไขที่ต้องการจะทดสอบซึ่งก็จะให้ผลลัพธ์แบบเดียวกับการใช้คำสั่ง test แต่การใช้เครื่องหมายก้ามปูจะทำให้บรรทัดคำสั่งดูเป็นระเบียบและเข้าใจง่ายกว่า สำหรับในคอร์นเชลล์จะใช้เครื่องหมายก้ามปูซ้อน "[[...]]" การใช้เครื่องหมายแบบนี้ในการทดสอบเงื่อนไขจะมีรูปแบบพิเศษที่เพิ่มเติมขึ้นมาจากการใช้คำสั่ง test หรือการใช้เครื่องหมายก้ามปูธรรมดา
$ [ ! -f /bin ]; echo $?
0
ตัวอย่างนี้จะใช้นิพจน์ทางตรรกะเข้ามาร่วมตรวจสอบเงื่อนไขด้วย คือเป็นการทดสอบว่าค่าตัวเลข 1 มากกว่า 2 และ ค่าตัวเลข 2 มากกว่า 3 หรือไม่ พิจารณาจากตารางทางตรรกะศาสตร์แล้ว ก็จะเห็นว่าผลลัพธ์ของ "จริง" และ "เท็จ" (T AND F) ก็จะได้ออกมาเป็นเท็จ ซึ่งก็จะตรงกับผลลัพธ์ที่เชลล์พิมพ์ออกมาให้
$ [ 1 -gt 2 -a 3 -gt 2 ]; echo $?
1
การใช้คำสั่งควบคุมทิศทางการทำงาน Flow control command
ผลลัพธ์ที่ได้จากการใช้คำสั่ง test ทำการทดสอบเงื่อนไขนี้ เราสามารถนำมาใช้เป็นเงื่อนไขของการควบคุมทิศทางการทำงานของโปรแกรมได้ ซึ่งก็จะขึ้นอยู่กับรูปแบบของคำสั่งที่ควบคุมทิศทางต่างๆว่าจะจัดการกับเงื่อนไขที่เป็นจริงอย่างไร และจะจัดการกับเงื่อนไขที่เป็นเท็จอย่างไร
การควบคุมทิศทางการทำงานของโปรแกรมโดยใช้ชุดคำสั่งแบบ ถ้า...แล้ว (if...then)
รูปแบบของคำสั่ง
-
if
then
command list
else
command list
fi
สำหรับคำสั่งควบคุมทิศทางแบบ ถ้า...แล้ว นี้หากเงื่อนไขที่ทดสอบคืนค่า exit code
ที่เป็นจริง (0) มาให้ก็จะทำคำสั่งหลัง "then" แต่ถ้าเป็นเท็จ (ไม่ 0) ก็จะทำชุดคำสั่งที่อยู่หลัง "else" คำสั่งควบคุมทิศทางแบบ ถ้า...แล้ว จะต้องทำการปิดชุดคำสั่งด้วยคำสำคัญ "fi" (เป็นตัวกลับหน้า-หลังกับ if)
ตัวอย่าง
if [ -d $1 ]
then
echo $1 is a directory
else
echo $1 is not a directory
fi
ให้บันทึกชื่อไฟล์เป็น "ex3" แล้วทำการเปลี่ยนโหมดเป็นโหมดที่สามารถสั่งให้ทำงานได้จากนั้นสั่งทำงานโปรแกรมดังต่อไปนี้
$ ex3 /bin
/bin is a directory
-
if
then
command list
elif
then
command list
else
command list
fi
สำหรับคำสั่งควบคุมทิศทางแบบ ถ้า...แล้ว รูปแบบที่สองนี้จะคล้ายกับแบบแรก เพียงแต่มีการเพิ่มเติมการตรวจเงื่อนไขเพิ่มขึ้นมาอีกเงื่อนไขหนึ่ง ซึ่งเงื่อนไขนี้จะอยู่ตามหลังคำบังคับ "elif" หากเงื่อนไขตรงนี้เป็นจริง ก็