文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Linux Shell Script

Linux Shell Script

时间:2006-10-14  来源:hubble.king

程式化 Bash Shell

到底需不需要程式化 Bash Shell,這個問題就依管理者自己所處的環境而定,如果需要對資料做條件式判斷、同一時間重覆多次命令或條件式回應,那麼這就需要讓 Shell Script 程式化了。

基本上 Bash Shell 本身就提供了程式功能,以便管理者能便有彈性的去強化 Script 檔,讓主機的管理便方便。當然,您不必覺得太惶恐,因為這不像寫 C 一樣這種大工程,寫 Bash Script 的成就感可能會大於寫 C 的成就感,因為你可以很容易的就上手,不用 include 什麼標頭檔,如果出錯時也會很容易的知道自已錯的地方在那裡。在本章,我們只討論 if ... elif ... else ...fi 、for ... do ... done、case ... esac 的常用語法。 判斷式

if [ 條件一 ]; then
  執行一
elif [ 條件一 ]; then
  執行二
else
  執行三
fi

多個條件

在 if 裡的條件式裡,同一個判斷行可以有很多的條件,可以使用邏輯運算符號來表示:

&& 且
|| 或
== 等於
if [ "$TEST1" == "1234" ] && [ "$TEST2" == "45678" ]; then

上面這句話的意思就是說當變數 $TEST1 等於 1234 並且 變數 $TEST2 等於 45678 的時候才做動作,否則跳到下一個條件式。

if [ "$TEST1" == "1234" ] || [ "$TEST2" == "45678" ]; then

上面這句話的意思就是說當變數 $TEST1 等於 1234 或變數 $TEST2 等於 45678 的時候(亦即兩個條件只要一個成立)就做動作,否則跳到下一個條件式

檔案判斷

以下是常用的檔案判斷

檔案、目錄的類型判斷

-f:檢查檔案是否存在
-d:檢查目錄是否存在
-e:檢查檔案或目錄是否存在
範例 if [ -f /etc/fstab ]; then

if [ -d /etc ]; then

if [ -e /etc ]; then

檔案、目錄的權限判斷

-r:檢查該檔案、目錄是否可讀
-w:檢查該檔案、目錄是否可寫
-x:檢查該檔案、目錄是否可執行
範例 if [ -r /etc/fstab ]; then
  echo "You can read this file."
fi
if [ -w /etc/fstab ]; then
  echo "You have the \"write\" permission for this file."
fi
if [ -x /etc/fstab ]; then
  echo "You have the \"execute\" permission for this file."
fi

解釋

上面的三個列子,會逐一簡查 /etc/fstab 這個檔案是否可以讀取、寫入和執行,如果符合就顯示相關訊息。如果您是以 root 身份來執行的話,那麼結果應該會顯示 You can read this file.
You have the "write" permission for this file.

的樣示。

選擇式判斷 case 值 in
參考值一)
  執行一
  ;;
參考值二)
  執行二
  ;;
參考值三)
  執行三
  ;;
*)
  執行預設動作
  exit 1
esac

case 可以讀取所給的值,然後再依序尋找相符的條件,如果符合就執行動作,若都沒有找到符合的,就執行預設動作。

範列 test=1
case $test in
1)
  echo "Value 1"
  ;;
2)
  echo "Value 2"
  ;;
3)
  echo "Value 3"
  ;;
*)
  echo "Can not find the value."
  exit 1
esac

解釋

首先先設定一個變數 test,然後在使用 case 讀到 test 的變數值,再依續判斷是否有符合條件的,如果有就執行動作,若沒有就執行預設動作。在本例中,會顯示 Value 1

的字樣。

迴圈 for 變數 in 已宣告的變數集值
do
  要重覆的動作
done

範列 NAME="Steven Tom Lisa Sandy"

for i in $NAME
do
  echo $i
done

解釋

首先先設定 NAME 的字串集合,然後在 for 裡建立一個變數 i 去讀取 NAME 的變數值,再依續顯示出來。在本列中,會顯示 Steven
Tom
Lisa
Sandy
UNIX Shell Script
UNIX Shell本身是一個交談式的命令環境,也是一個功能強大的譯式程式語言(Interpreter)。一般我們稱以UNIX Shell 寫成的程式為Shell Script。不同的Shell語法,會有一定程度的差異。

Borne Shell(/bin/sh)是UNIX作業系統中最早存在的Shell,在所有的UNIX版本中均可發現他的存在,Borne Shell的語法適合Shell命令程式的寫作。

UNIX Shell Script 的內容為UNIX指令與一些控制及迴圈指令的組合。

UNIX Shell Scirpt的第一行開頭為符號"#!"加上所用Shell名稱,其用意為告訴kernel,這是一個可執行的程式,同時執行時的環境為所指定的shell(缺少這一行,執行時可能會遭遇到不可預期的錯誤)。

Shell Script是一種"Free Format"的程式,除了控制迴圈須注意結構完整性外,程式本身並無特殊的格式。下面是一個Borne Shell的例子:

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

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

關於變數

設定變數方式為
var=value

取用變數的方法為
$var

Exmaple 1:
#!/bin/sh
woody="吳賢明 的小名"
echo $woody

(local)變數的設定,會在在同一個process中持續存在,一直到此process結束。

Shell中,變數的值可以含有space的字串,帶有一個以上space的的變數,給定值的時候,必須以成對的雙引號( " )或單引號(')涵蓋之。

雙引號( " )中若含有變數($var),會先將變數轉換成其實際的值,單引號(')則會將$var當成是一個值,而不會作轉換動作。

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

結果:
1.woody 就是 吳賢明 的小名
2.woody 就是 $woody

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 !!)

訊息列印

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 monitor。Variables between
these two SEGMENT1's will be calculated before any processing。
Yo umay try the following:
var1=$var1
var2=$var2
SEGMENT1

Another Example:

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

這個程式執行的結果為:
Strings between the two "SEGMENT1"s will be treated as
constant,and printed out from the monitor。Variables between
these two SEGMENT1's will be calculated before any processing。
Yo umay try the following:
var1=變數一
var2=變數二
Another Example:
這是避免變數被解釋的方法,請注意義以下字串被列印
出來的結果:
var1=$var1
var2=$var2

read - 從銀幕讀入一個變數
Example 5:
#!/bin/sh
echo -e "Please input your name: \c" #(\c迫使游標不換行)
read name
echo "Hello, $name"

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)。

test指令 (or [])
if控制迴圈中的condition值只有真(0)與偽(none zero)兩種,test指令(or [])提供了判斷真與假的功能。

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

Case 指令(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

while 指令
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執行的結果

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

 

trap - Trapping Signal

Signal 是UNIX系統中用來傳遞控制訊息(由一程序到另一程序)的一種機制。

一個Process收到signal之後,會優先處理(將控制權交出),處理完畢之後在行返回元程序繼續執行(重新取回控制權)。

Signal為一非同步訊息,由數字所構成。不同的數字所代表不同的控制訊息及不同的處理步驟,例如signal "2" (按下Ctrl+C"會送出這個訊號)代表結束目前程序。Programmer也可以在程式撰寫時,重新定義Signal。『trap』是在bash環境下,可供程式撰寫者重設SIgnal的工具。

利用shell programming撰寫程式時,使用trap通常是希望能夠避免使用者以不正常方式中斷程式,而使程式進入一個不可知的狀態,危害到系統運作,或取得不正當的存取權限。UNIX Signal種類,及所代表的意義,請參考講義『UNIX Process』。常用的HotKey與Signal的對應如下:
Ctrl+C   2
Ctrl+\   3
Ctrl+Z   20

trap格式
trap 'commands; command'   signal_number
當程序收到"signal_number"時,會屏除系統預設處理步驟,改以執行單引號中的指令代之。
Example:
trap 'echo "Why You Use Ctrl+C ? Don't Do That Again !!!" 1
如果你在shell script中(程式最上頭)加上這行指令,則當使用者(這執行這個程式時)按下Ctrl+C(預設動作為結束程式),銀幕上會印出"Why You Use Ctrl+C ? Don't Do That Again !!!",並繼續程式的執行。

Example :9 以下的例子是一個交談式的新帳號建立程式

#!/bin/sh
ID=`whoami`
if [ $ID != "root" ]
then
  cat << SEGMENT1
 
  ***********************************************
 
          你不是系統管理者!!  
   
    這個程式以交談式方式幫你建立使用者帳號,
  你必須具備SuperUser權限。  
   
  ***********************************************
 
  SEGMENT1
  exit 1
fi
 
echo -e "\n\n請輸入使用者帳號:\c"
read login
echo -e "\n請輸入使用者姓名:\c"
read comment
echo -e "請輸入使用者密碼(你將看不到你的輸入):\c"
password=`./inp`
 
# "inp"是Woody老師寫的一隻小小程式,功能在避免
# 使用者key-in文字在銀幕Show出,Source請參見nmc anonymous
# ftp linux目錄下的inp.c,Compile with " cc -o inp inp.c "

echo -e "請再輸入一次:\c"
password1=`./inp`

if [ $password != $password1 ]
then
  echo "兩次輸入密碼不一致,請再試一次"
  exit 1
fi

adduser -c $comment $login

if [ $? -eq 0 ]
then
  echo "Account $login Created !"
  echo "$login:$password"|chpasswd
 
  #chpasswd是系統指令,讀入"username:password" Pair(From File),將帳號"username"的密碼改成"password"

else
  echo "Account Not Created !! "
fi

echo"";echo ""

Example :10 以下的例子是一個交談式的使用者帳號密碼更改程式(This Program is for root only!)

#!/bin/sh
trap "" 2 3 20
echo -e "\n\n\n"

if [ ! -x /usr/sbin/inp ]
then
  echo -e "/usr/sbin/inp Needed, Please CHECK IT OUT !!!\n\n\n"
  exit 1
fi

echo -e "請輸入你要更改密碼的帳號: \c"
LOGNAME=`whoami`
read login
if [ $LOGNAME != "root" ]
then
echo "You are Not Authorized to change OTHER'S Passwprd ...!"
exit 1
fi

grep ^$login":" /etc/passwd > /dev/null

if [ $? -eq 0 ]
then
  echo -e "You New Password ....:\c"
  passwd=`/usr/sbin/inp`
  echo -e "You New Password Again....:\c"
  passwdagain=`/usr/sbin/inp`
  if [ $passwd = $passwdagain ]
  then
    echo "$login":"$passwd" | /usr/sbin/chpasswd
    if [ $? -eq 0 ]
    then
        echo "Passwdord For $login Changed !"
    else
        echo "Password Not Changed, Please Try again !"
    fi
  else
    echo "Password Not Match, Please Try Again.."
  fi
else
  echo "User Not Exist, Please Check it OUt !"
fi

echo -e "\n\n\n"

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. 請重新改寫Example 8 with command "until" !
5. 請寫一個shell script:
(1).提示使用者輸入username
(2).若此user存在,輸出『此使用者存在,請輸入下一筆資料』
(3).若此user不存在,輸出『此使用者不存在,請重新輸入』
(4).若輸入為Esc鍵,則跳離此一程式。
提示:
(1).grep username /etc/passwd可檢查該user是否存在。
(2).echo $?可以檢查上一個指令是否執行成功。
(3).輸入特殊符號(或Hot Key)的方式為^v + Hot-key
TERM:终端类型
位置参数
位置参数:$1-$9
特殊参数:$0 命令名
      $# 参数的个数
      $* 所有的参数
      $$命令的PID
实例:#Vi   /sys
  #!/bin/bash   (指定默认Shell)
  System=”RedHat Linux”
  Ech$1
  Ech$2
  Ech$System
  #chmod 755 /sys
  # /sys you need
  you need RedHat Linux
运算符
算术运算符:+,-,*,/,>>,<<
逻辑运算符:&&(与),||(或),!(非)
比较运算符:=(-eq),>(-gt),<(-lt),!=(-ne),<=(-le),>=(-ge)
操作符:-x (判断可执行文件是否存在)
        -f(判断普通文件是否存在)
        -r(判断只读文件)
        -w(判断可写文件)
        -s数字(判断文件大小)

用 bash 的话,目前都可以支援使用 $() 方式,多利用这个表示法比较方便
today=`date +%Y`
echo $today

echo $(date +%Y)
等价
相关阅读 更多 +
排行榜 更多 +
gg

gg

游戏工具 下载
超能格斗大师

超能格斗大师

动作格斗 下载
代驾司机管家

代驾司机管家

交通出行 下载