shell script

เราใช้พารามิเตอร์ -x ต่อท้ายคำสั่งในบรรทัดแรก

#!/bin/bash -x

จะมีผลว่าเชลล์จะแสดงทุกคำสั่งที่ถูกรันออกมาทางจอภาพ

จบแล้วจ้า

Taxonomy upgrade extras: 

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
Taxonomy upgrade extras: 

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')"
fi

11.3 ตัวดำเนินการทางคณิตศาลตร์ (Arithmetic operators)

  • + การบวก
  • - การลบ
  • * การคูณ
  • / การหาร
Taxonomy upgrade extras: 

10.1 การสั่งรันสคริปต์และคำสั่ง source

การสั่งรันสคริปต์ในเชลล์ มีเกร็ดคือ

  • ถ้าเราใส่ชื่อสคริปต์พร้อมพาธ เชลล์จะค้นหาสคริปต์จากชื่อเต็มที่เราใส่ เช่น
    $ /bin/ls
  • ถ้าเราใส่ชื่อสคริปต์โดด ๆ เชลล์จะค้นหาสคริปต์จากตัวแปร $PATH โดยไม่สนใจไดเรกทอรีปัจจุบัน เช่น
    $ mycode

    หากค้นไม่พบ จะแสดงข้อผิดพลาด แต่หากต้องการสั่งรันสคริปต์ในไดเรกทอรีปัจจุบัน เราต้องใช้คำสั่งอ้างอิงคือ

    $ ./mycode
Taxonomy upgrade extras: 

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 คือออกจากโปรแกรม

Taxonomy upgrade extras: 

ในการใช้งานเชลล์สคริปต์แบบจริงจัง เราจำเป็นต้องเขียนฟังก์ชันเพื่อประโยชน์ในการเรียกใช้งานแบบซ้ำ ๆ เพื่อให้ประหยัดการเขียนโค้ด และให้โค้ดดูง่าย

มีรูปแบบเป็น

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

Taxonomy upgrade extras: 

คำสั่ง 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 ...

Taxonomy upgrade extras: 

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.]
fi

6.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

ตัวอย่างนี้จะเป็นเท็จเสมอ

Taxonomy upgrade extras: 

ตัวแปรในเชลล์สคริปต์ ไม่มีชนิดข้อมูล คือเราสามารถใช้ตัวแปรแทนตัวเลขหรืออักขระใด ๆ ก็ได้
โดยในขั้นตอนกำหนดค่า ไม่ต้องใช้เครื่องหมายใด ๆ นำหน้า แต่ตอนอ้างถึง ต้องใช้เครื่องหมาย $ นำหน้าตัวแปร

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/
Taxonomy upgrade extras: 

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 แบบใส่พารามิเตอร์กรอง

Taxonomy upgrade extras: 

Pages

Creative Commons License ลิขสิทธิ์ของบทความเป็นของเจ้าของบทความแต่ละชิ้น
ผลงานนี้ ใช้สัญญาอนุญาตของครีเอทีฟคอมมอนส์แบบ แสดงที่มา-อนุญาตแบบเดียวกัน 3.0 ที่ยังไม่ได้ปรับแก้