UNIX Shell Programming
首頁

UNIX Shell Programming (Borne Shell or /bin/sh)
 

bulletUNIX Shell Script
 
  1. UNIX Shell本身是一個交談式的命令環境,也是一個功能強大的譯式程式語言(Interpreter)。一般我們稱以UNIX Shell 寫成的程式為Shell Script。不同的Shell語法,會有一定程度的差異。
  2. Borne Shell(/bin/sh)是UNIX作業系統中最早存在的Shell,在所有的UNIX版本中均可發現他的存在,Borne Shell的語法適合Shell命令程式的寫作。
  3. UNIX Shell Script 的內容為UNIX指令與一些控制及迴圈指令的組合。
  4. UNIX Shell Scirpt的第一行開頭為符號"#!"加上所用Shell名稱,其用意為告訴kernel,這是一個可執行的程式,同時執行時的環境為所指定的shell(缺少這一行,執行時可能會遭遇到不可預期的錯誤)。
  5. Shell Script是一種"Free Format"的程式,除了控制迴圈須注意結構完整性外,程式本身並無特殊的格式。下面是一個Borne Shell的例子:

#!/bin/sh
echo " This is a Borne Shell Script "

(為使你的Shell Script可以執行,你必須將這個Shell Script的執行權限"x"打開 : chmod +x shell_script)
 

bullet 關於變數
 
  1.  設定變數方式為

    var=value
  2. 取用變數的方法為

    $var

    Exmaple 1:
    #!/bin/sh
    woody="
    吳賢明 的小名"
    echo $woody
  3.  (local)變數的設定,會在在同一個process中持續存在,一直到此process結束。
  4.  Shell中,變數的值可以含有space的字串,帶有一個以上space的的變數,給定值的時候,必須以成對的雙引號( " )或單引號(')涵蓋之。
  5.  雙引號( " )中若含有變數($var),會先將變數轉換成其實際的值,單引號(')則會將$var當成是一個值,而不會作轉換動作。

    Example 2:
    1. echo "woody
    就是 $woody"
    2. echo 'woody
    就是 $woody '

    結果:
    1.woody
    就是 吳賢明 的小名
    2.woody 就是 $woody
  6.  Borne Shell中的內定變數
變數 變數意義
$# Number of arguments on the command line
$- Shell 的選項
$? Exit value of the last command executed ( in general, 0代表執行無誤,1代表指令有誤)
$$ Process number of the current process
$n Command line 中的參數,$0代表指令名稱,$1代表第一個參數,$2代表第二個參數....
$* Command line 中的所有參數

Example 3:
Shell Script : var_test
#!/bin/sh
echo $#
echo $-
echo $?
echo $$
echo $0
echo $1
echo $2
echo $*

執行 var_test 1 2 3 4 5
結果? (Try it !!)

 

bullet訊息列印
 
echo 指令可以讓你一次在銀幕上列印出一行字串(with Double quote『"』 or Single quote『'』),以下的方式可以讓你一次印出一段文章:

Example 4:
#!/bin/sh
var1="
變數一"
var2="
變數二"
cat << SEGMENT1
Strings between the two "SEGMENT1"s will be treated as
constant
and printed out from the monitorVariables between
these two SEGMENT1's will be calculated before any processing

Yo umay try the following
var1=$var1
var2=$var2
SEGMENT1

cat << \SEGMENT2 ##<--
請注意這行中的符號『\
這是避免變數被解釋的方法,請注意義以下字串被列印
出來的結果:
var1=$var1
var2=$var2
SEGMENT2


這個程式執行的結果為:
Strings between the two "SEGMENT1"s will be treated as
constant
and printed out from the monitorVariables between
these two SEGMENT1's will be calculated before any processing

Yo umay try the following
var1=變數一
var2=變數二
這是避免變數被解釋的方法,請注意義以下字串被列印
出來的結果:
var1=$var1
var2=$var2
bulletread - 從銀幕讀入一個變數

Example 5:
#!/bin/sh
echo -e "Please input your name: \c" #(\c
迫使游標不換行)
read name
echo "Hello, $name"

 
bullet if 指令

 Borne Shell中,if指令的用法為
if condition
then
command(s)
[elif condition
then command(s)]
[else
command(s)]
fi

中括號([])表示可有可無。

 Example 6:
#!/bin/sh
ls -l /etc/host.conf
if [ $? -eq 0 ]

then
echo "/etc/host.conf is there !!"
else
echo "/etc/host.conf is not there !!"
fi

註[$var -op value]可以比對$var與value ($var為數值變數)。op的值有gt (greater then),eq(equal to ),lt(less than),ge (greater than or equal to ),ne(not equal)及le(less than or qual to)。

 
bullettest指令 (or [])
 
  1.  if控制迴圈中的condition值只有真(0)與偽(none zero)兩種,test指令(or [])提供了判斷真與假的功能。
  2.  test可提供檔名、字串與數值等真與偽的判斷

    檔名
    test -options file_name or [-option file_name]
    常用option與其所代表的意義如下:
    -r
    True if file exists and readble
    -w
    True if file exists and writadble
    -x
    True if file exists and executadble
    -f
    True if file exists and is a regular file
    -d
    True if file exists and is a directory
    -u
    True if file exists and is setuid
    -s
    True if file exists and is greater than zero in size

    字串
    test -option string or [-option string]
    常用option與其所代表的意義如下:
    -z
    True if string length is zero
    -n
    True if string length is non-zero
    test string1 = string2 or [string1 = string2]
    * True if string1 is identical to string2
    test string1 != string2 or [string1 != string2]
    --> True if string1 is not identical to string2

    數值
    test n1 -op n2 or [n1 -op n2]
    常用op(運算元)與其所代表的意義如下
    -eq
    True if n1and n2 are equal
    -ne
    True if n1and n2 are not equal
    -gt
    True if n1 is greater than n2
    -ge
    True if n1 is greater than or equal tp n2
    -lt
    True if n1 is less than n2
    -le
    True if n1 is less than or equal to n2
    ** Both n1 & n2 are intergers
bulletCase 指令(Conditional Swith)

case 指令的語法
case variable in
pattern1[|pattern1a]) commands ;;
pattern2) commands;;
....
*) commands ;;
esac

Example 7:
#!/bin/sh
cat << EOF
****************************************
a.I need a banana.
b.I need an orange.
c.I need an apple.
****************************************
EOF
read choice
case $choice in
a|A) echo "You need a banana !!" ;;
b|B) echo "You need an orange !!" ;;
c|C) echo "You need an apple !!" ;;
*) echo "Bad choice, see yo next time !!";;
esac

 
bulletwhile 指令

while 指令語法
while condition
do
commands
done
##迴圈中commands會一直被重複執行直到condition 的值為偽為止。

Example 8:計算從1加到10並把結果印出
#!/bin/sh
NO=11
START=1
SUM=0
while [ $NO -gt 0 ]
do
SUM=`expr $START + $SUM`
START=`expr $START + 1`
NO=`expr $NO - 1`
done
echo "The answer is $SUM"


說明:
1. Shell中把所有變數均當成字串,因此進行整數運算時,必須特別註明。內建function "expr"可以幫我們進行這樣的數值計算。
2. 符號 ` 代表在變數給定的運算式中,帶有指令或函數。設定變數必須先行運算,再做設定。例如
HOSTNAME=`/bin/hostname`
則$HOSTNAME的值會是指令/bin/hostname執行的結果

 
bulletuntil 指令

until 指令語法
until condition
do
commands
done

##until指令用法與while恰巧相反;迴圈中commands會一直被重複執行直
到condition 的值為真。
請試著以until重寫上面數字累加的例子。

 
bulletSome other examples

Example 9: Time CountDown
#!/bin/sh
count=8
while [ $count -gt 0 ]
do
clear
/usr/games/banner -w 64 $count
echo -e "\a"
count=`expr $count - 1`
sleep 1
done
echo -e "Time is up \a!"


Example 10: Add an new user interactively
#!/bin/sh
clear
echo "This shell create a new user interactively ...."
echo -e "Please enter login name : \c"
read name
grep "^$name" /etc/passwd > /dev/null
if [ $? -eq 0 ]
then
echo "User exists, try again !"
else
touch usertmp
echo -e "Enter Password For $name:\c"
read password
echo "$name:$password" > /tmp/usertmp
adduser $name
chpasswd < /tmp/usertmp
if [ $? -eq 0 ]
then
echo "User $name Created ..."
else
echo "User Creation Fail, Try Again .."
fi
rm /tmp/usertmp
fi


 


 

Exercise:

  1. 請將講義Example 1~ 8親自做一次,並確實了解其語意(Know HOW)。
     
  2. token=super
    請問下面指令會得到什麼結果?你知道為何如此嗎?
       echo $tokenman
       echo '$token'man
       echo "$token"man

     
  3. 請寫一shell script
    (1).提示使用者選擇1.可連(telnet)至ccsun, 2.可連(telnet)至bbs, 3. 可連(telnet)至nmc.nchu.edu.tw
    (2).從鍵盤(keyboard)讀取變數『Choice』
    (3).IF Choice=1 --> telnet to ccsun
         IF Choice=2 --> telnet to bbs
         IF Cjoice=3 --> telent to nmc.nchu.edu.tw
    Otherwise Say something to user, and terminate the program
     
  4. 請寫一個shell script:
    (1).提示使用者輸入username
    (2).若此user存在,輸出『此使用者存在,請輸入下一筆資料』
    (3).若此user不存在,輸出『此使用者不存在,請重新輸入』
    (4).若輸入為Esc鍵,則跳離此一程式。
    提示:
    (1).grep username /etc/passwd可檢查該user是否存在。
    (2).echo $?可以檢查上一個指令是否執行成功。
    (3).輸入特殊符號(或Hot Key)的方式為^v + Hot-key
  5. 整批使用者建檔:
    請參考Example 10., 寫一個交談式快速建立多個使用者帳號的程式。
    程式輸入:
    (1).建立帳號個數
    (2).帳號名稱prefix(例如net)
    程式輸出:
    (1).建立帳號為net1,net2,net3.....的帳號,帳號個數為你輸入的數目
    (2).帳號密碼為"nchu+帳號名稱"(例如:nchunet1, nchunet2...)