Shell Script

ผู้เขียน/โดย : เกริก ภิรมย์โสภา (Krerk Piromsopa)
เขียนเมื่อ/ปรับปรุง : 2004-07-14 16:56:02

เอกสารนี้จัดทำขึ้นเพื่อแนะนำ และใช้สำหรับการอ้างอิงให้กับผู้ที่จะเขียนโปรแกรมบน
Shell โดยจะกล่าวถึงโครงสร้างโดยทั่วไปของ Shell แสดงการใช้คำสั่งต่างๆ
พร้อมตัวอย่างประกอบ ทั้งนี้ตัวอย่างดังกล่าวจะเปรียบเทียบระหว่าง bash
, ksh และ tcsh เป็นหลัก โดยข้อมูลในเอกสารนี้จะเน้นเพียงข้อมูลที่เป็นมาตรฐานของ
Shell ทั่วไปเท่านั้น เนื่องจากในปัจจุบัน Shell หมายๆ ตัวได้มีการปรับปรุงให้ทำงานได้กว้างมากขึ้น
และ เขียนง่ายยิ่งขึ้นเช่น bash บน Linux ซึ่งจะรวมความสามารถของ ksh และ
tcsh หลายอย่างไว้ด้วยกัน เป็นต้น

ลักษณะทั่วไปของ Shell

หน้าที่พื้นฐานของ Shell โดยทั่วไปนั้นคือการรับคำสั่งจาก
User เพื่อทำการบอก OS ให้ Load และ Run Program ต่างๆ อย่างไรก็ตามได้มีการพัฒนาให้
Shell มีความสามารถในการประมวลผลคำสั่งต่างๆ เพื่อให้ทำงานในลักษณะของ
Batch ได้ ทั้งนี้โครงสร้างของโปรแกรมต่างๆ หรือ Shell นั้นจะประกอบด้วยตัวแปรระบบ
หรือ สภาวะแวดล้อม(Envirenment) ซึ่งพร้อมที่จะส่งให้โปรแกรมอื่นๆ ประมวลผลต่อ
ประโยคเงื่อนไขต่างๆ ระบบ Profile สำหรับวัดเวลาในการประมวลผลของโปรแกรมต่างๆ
และ User Defined Function

ในการวัดเวลาที่ใช้ในการทำงานคำสั่งต่างๆ ของ Unix นั้นสามารถทำได้โดยใส่
time นำหน้าคำสั่งที่ต้องการประมวลผล ซึ่งโปรแกรมจะบอก OS ให้ทำการจับเวลา
และ รายงานผลเวลาที่ใช้ในการประมวลผลหลังจากทำงานเสร็จ เช่น

time ls -al /bin/*

สำหรับกรณี Shell บน Unix นั้น การเขียนคำสั่งแต่ละคำสั่งจะต้องจบคำสั่ง
ด้วยบรรทัดใหม่ หรือ เครื่องหมาย semi-colon เสมอ “;” และกรณีที่คำสั่งมีความยาวมาก
(ไม่จบภายใน 1 บรรทัด) ให้จบบรรทัดด้วยเครื่องหมาย “” แล้วพิมพ์ต่อในบรรทัดถัดไป
เช่น

echo “Test”; ls;

echo “Hello

world”

การเขียน Comment ใน Shell Script จะใช้เครื่องหมาย “#”

ทั้งนี้ในการเขียนโปรแกรมที่เป็นภาษา Script ต่างๆ บน Unix
นั้น ในบรรทัดแรกเราควรจะระบุชื่อโปรแกรมที่จะทำการประมวลผล Script นั้นๆ
ไว้ด้วยเช่น

#! /bin/ksh

หรือ กรณีเป็น Perl อาจจะเขียนเป็น

#! /usr/bin/perl

เป็นต้น

การใช้งาน Variable / Environment

บนระบบ OS โดยทั่วไปมักจะมี Environment
หรือ System Variable เพื่อส่งผ่านค่าระหว่างโปรแกรมต่างๆ ภายในระบบ เสมอ
ซึ่งโดยทั่วไปเราจะอ่านค่า Environment (ของ OS เกือบทุกตัว) ได้โดยการใช้คำสั่ง
set

ตัวอย่างการตั้งค่า Variable ใน Shell เช่น

bash / ksh tcsh
myname=”Krerk Piromsopa”count=5; set myname=”Krerk Piromsopa”set count=5;

นอกจากนี้เรายังสามารถนำผลลัพธ์จากการ Run Programm อื่นๆ
มาเป็นค่า Variable ได้อีกด้วย โดยใช้ Back Quote แทน หรือ Run คำสั่งภายในเครื่องหมาย
$(command) เช่น

bash / ksh tcsh
list = `ls`# หรือ
list=$(ls)
set list = `ls`# หรือ

set list=$(ls)

ทั้งนี้หากต้องการให้ค่า Variable หรือ Environment คงอยู่หลังจากที่
Run Shell สามารถทำได้โดยการ export เช่น

export myname,count

นอกจากนี้ยังมีตัวแปรระบบที่จะใช้สำหรับการอ้างอิงในโปรแกรม
Shell ได้อีกด้วย เช่น

ตัวแปร ความหมาย
$# แสดงจำนวน Parameter ที่ส่งมาให้กับระบบ
$? เก็บค่าที่ได้จากประมวลผลคำสั่งก่อนหน้านี้
$0 แสดงชื่อของ โปรแกรมที่กำลังประมวลผลอยู่
$* เก็บค่า Parameter ทุกตัวที่ใช้ในการประมวลผล ($1 $2 ….)
“$@” เก็บค่า Parameter ทุกตัวที่ใช้ในการประมวลผล (“$1″ “$2″
….)

การใช้งาน Variable ทุกตัวนั้นจะเป็น Implicit Declaration
กล่างคือผู้ใช้ไม่จำเป็นต้องประกาศตัวแปร เช่นในภาษา C หรือ ภาษาชั้นสูงอื่นๆ
และ เมื่อต้องการยกเลิกตัวแปรนั้นสามารถทำได้โดยใช้คำสั่ง unset varname
เช่น

unset myname

test และ expression

บน bash และ ksh จะมีคำสั่ง Test และการเขียนเงื่อนไขในการตรวจสอบ
Expression ต่างๆ ในการเขียนประโยคเงื่อนไขต่าง ซึ่งมีโครงสร้างการเขียนดังนี้

test expression

หรือ

expression  ]

สำหรับ tcsh นั้นจะไม่มีคำสั้ง test แต่จะมีการนำ
expression เพื่อไปใช้ในการประมวผลผลคำสั่งต่างๆ เช่นกัน

ทั้งนี้ expression บน bash กับ ksh และ
tcsh นั้นจะมีโครงสร้างที่แตกต่างกัน ดังอธิบายได้ดังต่อไปนี้

bash / ksh tcsh ความหมาย
คำสั่งเกี่ยวกับจำนวนเต็ม
int1 -eq int2 int1 == int2 เป็นจริงเมื่อ int1 เท่ากับ int2
int1 -ge int2 int1 >= int2 เป็นจริงเมื่อ int1 มากกว่าหรือเท่ากับ int2
int1 -gt int2 int1 > int2 เป็นจริงเมื่อ int1 มากกว่า int2
int1 -le int2 int1 <= int2 เป็นจริงเมื่อ int1 น้อยกว่าหรือเท่ากับ int2
int1 -lt int2 int1 < int2 เป็นจริงเมื่อ int1 น้อยกว่า int2
int1 -ne int2 int1 != int2 เป็นจริงเมื่อ int1 ไม่เท่ากับint2
คำสั่งเกี่ยวกับ String
str1 = str2 str1 == str2 เป็นจริงเมื่อ str1 เหมือนกับ str2
str1 != str2 str1 != str2 เป็นจริงเมื่อ str1 ไม่เหมือนกับ str2
str เป็นจริงเมื่อ str ไม่เป็น null
-n str เป็นจริงเมื่อ str มีความยาวมากกว่า 0
-z str เป็นจริงเมื่อ str มีความยาวเป็น 0
คำสั่งเกี่ยวกับ file
-d filename -d filename เป็นจริงเมื่อ filename เป็น directory
-f filename -f filename เป็นจริงเมื่อ filename เป็น file
-r filename -r filename เป็นจริงเมื่อ filename อ่านได้โดยโปรแกรม
-s filename เป็นจริงเมื่อ filename มีขนาดไม่เป็น 0
-w filename -w filename เป็นจริงเมื่อ filename เขียนได้โดยโปรแกรม
-x filename -x filename เป็นจริงเมื่อ filename run ได้โดยโปรแกรม
-e filename เป็นจริงเมื่อ filename มีชื่ออยู่
-o filename เป็นจริงเมื่อ filename เป็นของผู้ใช้ปัจจุบัน
-z filename เป็นจริงเมื่อ filename มีขนาดเป็น 0
คำสั่งเกี่ยวกับ Logical อื่นๆ
! expr ! expr เป็นจริงเมื่อ exp เป็นเท็จ
exp1 -a exp2 exp1 && exp2 เป็นจริงเมื่อ exp1 และ exp2 เป็นจริง
exp1 -o exp2 exp1 || exp2 เป็นจริงเมื่อ exp1 หรือ exp2 เป็นจริง

เงื่อนไข if

โครงสร้าง

bash / ksh tcsh
if [expression ]

then

commands

elif [ exprression ]

then

commands

else

commands

fiif (expression) then

commands

else if (expression) then

commands

else

commands

endif

ทั้งนี้จะมี elif หรือ ไม่มี else ก็ได้

ตัวอย่างการใช้งาน เช่น

#! /bin/ksh

if [ -f .signature ]

then

echo “There is .signature file in
this current directory”

else

echo “File .signature could not be
found.

fi

เงื่อนไข case หรือ switch

โครงสร้าง

bash / ksh tcsh
case string  in

str1)

commands;;

str2)

commands;;

str3)

commands;;

*)

commands;;

esacswitch(string)

case str1:

commands

breaksw

case str2:

commands

breaksw

case str3:

commands

breaksw

default:

commands

breaksw

endsw

ในกรณีของ bash และ ksh นั้น จะใช้ ;; แทน break

ตัวอย่างการใช้งาน เช่น

#! /bin/ksh

# Sample switch case

if [ $# -lt 2 ]

then

echo “Using : $0 [a | b | c] filename”

else

case $1 in

“a” | “A”)

cat $2;;

“b” | “B”)

&nsbp; more $2;;

“c” | “C”)

less $2;;

*)

echo “I Don’t understand $1″

esac fi

เงื่อนไข for

โครงสร้าง

bash / ksh tcsh
for var in list

do

commands

doneforeach var (list)

commands

end

ตัวอย่างการใช้งาน เช่น

#! /bin/ksh

# Sample for

for x in “a ” “b” “x*”

do

if [ -f "$x" ]

then

echo “— found $x —”

else

echo “— Not found $x —”

fi

เงื่อนไข while

โครงสร้าง

bash / ksh tcsh
while [ expression ]

do

commands

donewhile (expression)

commands

end

ตัวอย่างการใช้ while เช่น

#! /bin/ksh

count=1

while [ -n "$*" ]

do

echo “This is parameter no $count $1″

shift

count=`expr $count+1`

done

เงื่อนไข until

โครงสร้าง

bash / ksh tcsh
until [ expression ]

do

commands

doneไม่สนับสนุน

เงื่อนไข repeat

bash / ksh tcsh
ไม่สนับสนุน repeat count command

ตัวอย่างการใช้ repeat เช่น

#! /bin/tcsh

repeat $num echo -n “+”

echo “”

คำสั่งอื่นๆ ที่ช่วยให้เขียน Interactive
Shell Script ได้ง่ายขึ้น

คำสั่ง read

ใช้สำหรับอ่านค่าตัวแปรจาก Standard Input เช่น

#! /bin/ksh

echo -n “Enter FirstName Lastname”

read x y

echo “”

echo “Your firstname is $y, $x.”

คำสั่ง echo

ใช้เพื่อการแสดงข้อความ

คำสั่ง shift

ใช้สำหรับการ Shift ค่าตัวแปรใน $* ไป 1 ตำแหน่ง

การสร้างคำสั่งใหม่ (Function)

โครงสร้าง

bash / ksh tcsh
[function] fname {

(shell commands)

}ไม่สนับสนุน

ซึ่งเราสามารถเรียกใช้ Function ได้โดย

fname [ parm1 parm2 parm3 ... ]

ตัวอย่างเช่น

#! /bin/bash

print () {

echo $1 $2;

}

a=10;

b=20;

print $a $b

การประมวลผลทางคณิตศาสตร์ และ expression

เราสามารถประมวลผลบวกลบคูณหาร หรือ expression ต่างๆ ได้โดยใช้โปรแกรม expr ช่วย เช่น

a=`expr $a + 1`  หรือ set a=`expr $a + 1`

ในกรณีของ bash เราสามารถใช้ a=$(($a + 1 )) แทนได้เลย

ข้อควรระวังคือ จะต้องมีการเว้นวรรคระหว่าง ตัวแปร ค่าคงที่ และ
เครื่องหมาย (มิเช่นนั้น จะได้ผลลัพธ์เป็น string ต่อกัน)
เครื่องหมายและการปฏิบัติการที่ใช้ได้ใน expr คือ +, -, *, / , % (modulo
หรือ หารเอาเศษ) นอกจากนี้ยังมีการเปรียบเทียบต่างๆ เช่น =, \<, \>,
\<=, \>=, และ != (กรณีใช้กับ bash $(( expression ))
ให้นำเครื่องหมาย \ ออก การเปรียบเทียบเหล่านี้จะให้ผลลัพธ์เป็น 0
หากเป็นเท็จ และ 1 หากเป็นจริง

เกร็ดเล็กน้อยเกี่ยวกับการใช้ expr

expr1 \| expr2

จะแสดงผลลัพธ์จาก expr2 หาก expr1 เป็น 0 หรือ NULL เช่น

expr 1 – 1 \| “zero”
จะได้ผลลัพธ์เป็น “zero” เนื่องจาก 1 – 1 = 0 เป็นต้น

expr1 \& expr2

จะแสดงผลลัพธ์จาก expr1 หาก ไม่มีอันใดเป็น 0 หรือ NULL เช่น

expr valid \& 3 – 2 \& 4
จะได้ผลลัพธ์เป็น “valid” เนื่องจากไม่มี expression ใด เป็น 0 เป็นต้น

expr1 : expr2

จะเปรียบเทียบ expr1 กับ expr2 ตามมาตรฐาน regular expression เช่น

expr $HOME : “.*home.*”
จะตรวจสอบว่ามีคำว่า home อยู่ใน $HOME หรือไม่ เป็นต้น

เอกสารอ้างอิง

  • T. Parker, Chapter 13 Shell Programming ,”Slackware Linux”,
    SAMS Publishing, 3rdEdition, 1997.
  • ksh , sh , tcsh , bash manpage.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Connect with Facebook

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>