shell script
13. การค้นหาที่ผิดในสคริปต์
Submitted by wd on 21 November, 2007 - 13:16.เราใช้พารามิเตอร์ -x ต่อท้ายคำสั่งในบรรทัดแรก
#!/bin/bash -x
จะมีผลว่าเชลล์จะแสดงทุกคำสั่งที่ถูกรันออกมาทางจอภาพ
จบแล้วจ้า
12.ตัวอย่างสคริปต์
Submitted by wd on 21 November, 2007 - 13:15.12.1 ตัวอย่างสคริปต์ดูรายชื่อไฟล์ในไดเรกทอรีย่อย
#!/bin/bash
function listdir {
local PAT="$1"
local ROOT="$2"
for i in *; do
if [ -d "$i" ]; then
local CUR="$ROOT/$i"
pushd "$i" &>/dev/null
listdir "$PAT" "$CUR"
popd &>/dev/null
fi
done
if [ ! -z "$( ls -d $PAT 2>/dev/null )" ]; then
echo "Directory: $ROOT"
ls -d $PAT 2>/dev/null
echo
fi
}
if [ -z "$1" ]; then
echo List file in PATTERN recursively into directories.
echo Usage: $0 "PATTERN"
exit
fi
PATTERN="$1"
echo "List $PATTERN"
listdir "$PATTERN" "."ให้ผลคล้ายคำสั่ง
$ find * -name PATTERN
12.2 ตัวอย่างสคริปต์บีบอัดสำรองข้อมูล
#!/bin/bash SRCD="/home/" TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cZf $TGTD$OF $SRCD
12.3 เปลี่ยนชื่อไฟล์ทีละหลายไฟล์
#!/bin/sh # renna: rename multiple files according to several rules # written by felix hudson Jan - 2000 #first check for the various 'modes' that this program has #if the first ($1) condition matches then we execute that portion of the #program and then exit # check for the prefix condition if [ $1 = p ]; then #we now get rid of the mode ($1) variable and prefix ($2) prefix=$2 ; shift ; shift # a quick check to see if any files were given # if none then its better not to do anything than rename some non-existent
11. ตัวดำเนินการ (operators) และคำสั่งน่าสนใจ
Submitted by wd on 21 November, 2007 - 13:14.11.1 ตัวดำเนินการเปรียบเทียบตัวอักษร (String comparison operators)
[ "$s1" = "$s2" ]หรือ[ "$s1" == "$s2" ]เป็นจริง ถ้า s1 เท่ากับ s2[ "$s1" != "$s2" ]เป็นจริง ถ้า s1 ไม่เท่ากับ s2[[ "$s1" < "$s2" ]]หรือ[ "$s1" \< "$s2" ]เป็นจริง ถ้า s1 น้อยกว่า s2[[ "$s1" > "$s2" ]]หรือ[ "$s1" \> "$s2" ]เป็นจริง ถ้า s1 มากกว่า s2[ -n "$s1" ]เป็นจริง ถ้า s1 มีค่าใด ๆ[ -z "$s1" ]เป็นจริง ถ้า s1 ไม่มีค่า
11.2 ตัวอย่างการเปรียบเทียบอักษร
#!/bin/bash
S1='string'
S2='String'
if [ "$S1" = "$S2" ]; then
echo "S1('$S1') is not equal to S2('$S2')"
fi
if [ "$S1" = "$S1" ]; then
echo "S1('$S1') is equal to S1('$S1')"
fi11.3 ตัวดำเนินการทางคณิตศาลตร์ (Arithmetic operators)
+การบวก-การลบ*การคูณ/การหาร
10.เกร็ดอื่น ๆ
Submitted by wd on 21 November, 2007 - 13:10.10.1 การสั่งรันสคริปต์และคำสั่ง source
การสั่งรันสคริปต์ในเชลล์ มีเกร็ดคือ
- ถ้าเราใส่ชื่อสคริปต์พร้อมพาธ เชลล์จะค้นหาสคริปต์จากชื่อเต็มที่เราใส่ เช่น
$ /bin/ls
- ถ้าเราใส่ชื่อสคริปต์โดด ๆ เชลล์จะค้นหาสคริปต์จากตัวแปร
$PATHโดยไม่สนใจไดเรกทอรีปัจจุบัน เช่น
$ mycode
หากค้นไม่พบ จะแสดงข้อผิดพลาด แต่หากต้องการสั่งรันสคริปต์ในไดเรกทอรีปัจจุบัน เราต้องใช้คำสั่งอ้างอิงคือ
$ ./mycode
9.การติดต่อผู้ใช้ (User Interfaces)
Submitted by wd on 21 November, 2007 - 13:09.9.1 ใช้คำสั่ง select ในการสร้างหัวข้อให้เลือก
#!/bin/bash
OPTIONS="Hello Quit"
select opt in $OPTIONS; do
if [ "$opt" = "Quit" ]; then
echo done
exit
elif [ "$opt" = "Hello" ]; then
echo Hello World
else
clear
echo bad option
fi
done
ตัวอย่างนี้จะสร้างหัวข้อ 1) และ 2) จากตัวแปร OPTIONS เพื่อมาให้เลือก โดยจะวนรอบถามไปเรื่อย ๆ จนกว่าจะพบคำสั่ง exit ให้ออกจากการวนรอบ
9.2 ใช้การตรวจสอบว่ามีการใส่ค่าพารามิเตอร์หรือไม่
#!/bin/bash if [ -z "$1" ]; then echo usage: $0 directory exit fi SRCD=$1 TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cZf $TGTD$OF $SRCD
บรรทัดที่ 2 จะตรวจว่ามีการใส่พารามิเตอร์ให้กับโปรแกรมหรือไม่ (if [ -z "$1" ] -z หมายถึงการตรวจสอบว่ามีค่าหรือไม่) ถ้าไม่มีการใส่ค่าพารามิเตอร์ โปรแกรมจะทำคำสั่งในบรรทัดที่ 3 คือแสดงวิธีใช้ ($0 คือชื่อโปรแกรมนี้) และบรรทัดที่ 4 คือออกจากโปรแกรม
8.ฟังก์ชั่น (functions)
Submitted by wd on 21 November, 2007 - 13:08.ในการใช้งานเชลล์สคริปต์แบบจริงจัง เราจำเป็นต้องเขียนฟังก์ชันเพื่อประโยชน์ในการเรียกใช้งานแบบซ้ำ ๆ เพื่อให้ประหยัดการเขียนโค้ด และให้โค้ดดูง่าย
มีรูปแบบเป็น
function FUNCTION_NAME {
COMMAND
}หรือ
FUNCTION_NAME () {
COMMAND
}
โปรแกรมจะเว้นไม่ถูกเรียกทำงานในช่วงตั้งแต่ชื่อฟังก์ชันจนกระทั่งจบบล็อก { COMMAND }
เรานิยมวางฟังก์ชันไว้ที่ต้นโปรแกรม เพื่อให้สามารถถูกเรียกจากโค้ดหลักได้
8.1 ตัวอย่างฟังก์ชัน
#!/bin/bash
function quit {
exit
}
function hello {
echo Hello!
}
hello
quit
echo foo
ตัวอย่างนี้ บรรทัดที่ 13 คือคำสั่ง echo foo จะไม่ถูกเรียกใช้ เนื่องจากโปรแกรมจะหลุดสู่เชลล์ในบรรทัดที่ 12 คือคำสั่ง quit
7.การวนรอบ โดยใช้คำสั่ง for, while และ until
Submitted by wd on 21 November, 2007 - 13:07.คำสั่ง for มีลักษณะคล้าย for ในภาษาไพธอน มีรูปแบบเป็น
for VAR in SCOPE; do
COMMAND
done
คำสั่ง while มีรูปแบบเป็น
while [ CONDITION ]; do
COMMAND
done
ตราบใดที่เงื่อนไข CONDITION ยังเป็นจริง ก็จะทำคำสั่ง COMMAND ซ้ำไปเรื่อย ๆ
คำสั่ง until มีความหมายตรงกันข้ามกับ while โดยมีรูปแบบเป็น
until [ CONDITION ]; do
COMMAND
done
คือจะทำคำสั่ง COMMAND จนกว่าเงื่อนไข CONDITION จะเป็นจริง
7.1 ตัวอย่าง for
#!/bin/bash
for i in $( ls ); do
echo item: $i
done
เป็นการนำผลลัพธ์ของคำสั่ง ls ไปเป็นตัวแปรชั่วคราวในการกำหนดขอบเขตให้กับตัวแปร i ในคำสั่ง for
ในที่นี้จะทำการแสดงผลว่า item: FILENAME ...
6. ประโยคเงื่อนไข
Submitted by wd on 21 November, 2007 - 13:06.6.1 รูปแบบ
มีรูปแบบคือ
if [ EXPRESSION ]; then
CODE IF 'EXPRESSION' IS TRUE.
[elif [ EXPRESSION-ELIF ]; then
CODE IF 'EXPRESSION-ELIF' IS TRUE.]
[else
CODE IF NOTHING IS TRUE.]
fi6.2 ตัวอย่าง if ... then
#!/bin/bash
if [ "foo" = "foo" ]; then
echo expression evaluated as true
fi
โค้ดนี้จะเป็นจริงเสมอ ดังนั้นข้อความ "expression evaluated as true" จะถูกพิมพ์ออกมาเสมอ
6.3 ตัวอย่าง if ... then ... else
#!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true else echo expression evaluated as false fi
โค้ดนี้จะเป็นจริงเสมอ ดังนั้นข้อความ "expression evaluated as true" จะถูกพิมพ์ออกมาเสมอ
6.4 ตัวอย่างแบบใช้ตัวแปร
#!/bin/bash
T1="foo"
T2="bar"
if [ "$T1" = "$T2" ]; then
echo expression evaluated as true
else
echo expression evaluated as false
fiตัวอย่างนี้จะเป็นเท็จเสมอ
5. ตัวแปร (Variables)
Submitted by wd on 21 November, 2007 - 13:05.ตัวแปรในเชลล์สคริปต์ ไม่มีชนิดข้อมูล คือเราสามารถใช้ตัวแปรแทนตัวเลขหรืออักขระใด ๆ ก็ได้
โดยในขั้นตอนกำหนดค่า ไม่ต้องใช้เครื่องหมายใด ๆ นำหน้า แต่ตอนอ้างถึง ต้องใช้เครื่องหมาย $ นำหน้าตัวแปร
5.1 ตัวอย่างสคริปต์ Hello World แบบใช้ตัวแปร
#!/bin/bash STR="Hello World!" echo $STR
ให้ผลลัพธ์เหมือนตัวอย่างที่ 2.1
ข้อควรระวังคือ
- การกำหนดค่าให้ตัวแปร อย่าเว้นวรรคระหว่างตัวแปรกับเครื่องหมาย
= - หากลืมใส่เครื่องหมาย
$จะหมายถึงการแสดงผลข้อความว่าSTRเฉย ๆ
5.2 ตัวอย่างสคริปต์สำรองข้อมูลแบบใช้ตัวแปร
#!/bin/bash OF=/tmp/my-backup-$(date +%Y%m%d).tgz tar -cvzf $OF /home/USER/
4. การส่งต่อผลลัพธ์ หรือ ไปป์ (Pipes)
Submitted by wd on 21 November, 2007 - 13:04.4.1 ความหมาย
ไปป์เป็นการส่งต่อผลลัพธ์จากคำสั่งหนึ่งไปเป็นค่านำเข้าของอีกคำสั่งหนึ่ง
4.2 ตัวอย่างไปป์
$ ls -l | sed -e "s/[aeio]/u/g"
ตัวอย่างนี้จะนำเอาผลลัพธ์ที่ได้จากคำสั่ง ls -l ส่งต่อไปให้คำสั่ง sed -e "s/[aeio]/u/g"
ซึ่งจะแปลงการแสดงผลจากอักขระ a หรือ e หรือ i หรือ o ไปเป็นอักขระ u ทั้งหมด
เราอาจเขียนคำสั่งเทียบเท่าได้ดังนี้
$ ls -l > temp.txt $ sed -e "s/[aeio]/u/g" temp.txt $ rm temp.txt
จะเห็นว่าการทำไปป์ ลดขั้นตอนไปมาก คงเหลือเพียงบรรทัดเดียว
4.3 ตัวอย่างไปป์ที่สอง
$ ls -l | grep "\.txt$"
ตัวอย่างนี้จะส่งผลลัพธ์จากคำสั่ง ls -l ต่อไปให้คำสั่ง grep "\.txt$" คือให้แสดงเฉพาะไฟล์ที่มีนามสกุลเป็น .txt เท่านั้น
มีค่าเท่ากับคำสั่ง ls แบบใส่พารามิเตอร์กรอง












