簡單的說shell就是一個包含若干行Shell或者Linux命令的文件。對於一次編寫,多次使用的大量命令,就可以使用單獨的文件保存下來,以便日後使用。通常shell腳本以.sh為後綴,第一行一定要指明系統需要哪種shell解釋用戶的shell程序,如:#!/bin/bash 、#!/bin/sh等。在這裡我們使用#!/bin/bash。
通常shell由Linux命令(外部命令)、Shell(內部命令),控制語句和注釋語句等組成,類似與windows下的批處理文件(.bat)。還需要注意的是我們需要使用 chmod +x name.sh執行shell腳本。
(一)變量和數組
1. 用type判斷是否是內部命令: type cmd
2. 變量賦空值的話,直接後面+回車,並且等號兩邊不能夠有空格。
3. echo $a 輸出a的值
4. export A,將A設成全局變量
顯示變量的值:echo $A ,{}是用來防止混淆的,例如輸出A的值後加上B字符:echo${A}B
5. 刪除變量:unset A
6. 顯示所有變量(包括本地):set ; set | grep A(顯示A變量); env 顯示全局變量(環境變量);初始化全局變量:export A=200。另外全局變量,按照慣例需要大寫:export LANG
注意:全局變量可被所有的shell環境下訪問;如果父Shell進程產生了子Shell進程,則環境變量可被“繼承”並復制
7. 只讀變量,指不能被清除或重新賦值的變量: readonly myvar
8. 位置參量(命令行參數):位置參量是一組特殊的內置變量,通常被shell腳本用來從命令行接受參數,或者被函數用來保存傳遞給他的參數。相當於C語言中的argv, 其中$1表示第一個參數,$2第二個....$9 以後要用花括號把數字括起來,${10};$0 代表當前腳本的文件名。
測試程序:
#!/bin/bash #測試位置參數和其他特殊參數 #使用方法:/target.sh 參數1 參數2 IFS=# echo shell script name is : $0 echo the count of parameters: $# echo first param=$1 echo second param=$2 echo '$*='$* #顯示所有的位置參數串 echo '"$*"="$*"' echo '$@='$@ echo '"$@"='"$@" echo '$$='$$ #顯示當前進程號 echo $!
數組定義和初始化:arr=(math Chinese English)
數組引用:1. 引用變量:${arr[0]} 2.數組個數:${#arr[*]} 3.所有元素:${arr[*]}
數組賦值:arr[0]=chemial
需要注意的是shell的數組可以不連續的,這也是區別於其他語言的地方,例如:arr[0], arr[1],arr[2],arr[5]是允許的,他們的輸出(如果之前賦值和下標相同的話),數組輸出是0 1 2 5 ,個數是4。
(二)輸入和輸出
-p 代表提示符; -t代表超時時間 ; echo $REPLY;echo -n 表示不會輸出回車;-e “\t”代表轉義選項
echo顏色輸出和光標定位\33表示轉義開始,格式為 [數字m,從光標開始時改變顏色
\33[30m -- \33[37m 設置前景色 \33[40m -- \33[47m 設置背景色 \33[y;xH 設置光標位置 示例: echo -e "\33[31mthis is a test" echo -e "\33[10;5H\33[31;46mthis is a test" echo -e "\33[0m"
(三)字符和測試語句
算術的擴展,注意:符號兩端一定要留有空格!
表達式測試:
字符串測試:
檢查空值
[ “$name” = “”]
[ ! “$name” ]
[ “X${name}” = “X” ]
注意:字符串測試的兩邊要有空格
也可以使用(( )),但是兩者是不一樣的,[]只能和-eq之類的符號配對,而(())只能和>,<=之類的符號配對。
另外[[ expr1 && expr2 ]]等也是可以的。(||)
測試的簡單總結:
(四)條件和循環語句
if語句:
if [ $# -ne 1 ];then echo Usage: $0 username exit 1 fi echo $1
注意:可執行語句塊,如果為空,需要使用shell提供的空命令”:”,即冒號。該命令不做任何事情,只返回一個退出狀態0。(shell下返回0為成功執行,返回1為失敗)
case語句:
#!/bin/bash case $1 in A) echo this is A ;; B|b) echo this is B or b ;; *) echo others ;; esac
for 語句:
循環的執行過程:執行第一輪循環時,將list中的第一個詞賦給循環變量,並把該詞從list中刪除,然後進入循環體,執行do和done之間的命令。下一次進入循環體時,則將第二個詞賦給循環變量,並把該詞從list中刪除,依次列推。當list中的全部被移走後,循環就結束了。
位置參量使用 $*、“$*”、$@、"$@",可以省略in list ,此時使用"$@"
也可以使用如下形式:
for((exp1;exp2;exp3)) do ... done打印字符三角形:
#!/bin/bash if [ $# -ne 1 ];then echo 'usage:$0' exit 1 fi if [ $1 -lt "5" -o $1 -gt "15" ];then echo 'usage : $0 ' echo ' where 5<=n<=15' exit 1 fi for((i=0;i<$1;i++)) do for((j=0;j<$[$1-$i-1];j++)) do echo -n " " done for((j=0;j<$[2*$i+1];j++)) do echo -n "*" done echo -ne '\n' done
while語句:
until 語句:
select 列表:
select是個無限循環,因此要記住用break命令退出循環,或用exit命令終止腳本。也可以按ctrl+c退出循環。另外select經常和case聯合使用。也可以省略in list,此時使用位置參量。
#!/bin/bash PS3="favorite pet?" select var in Dogs Cats Birds do case $var in Dogs) echo Dogs are my favorite pet break ;; Cats) echo Cats are my favorite pet ;; Birds) echo Birds are my favorite pet ;; *) echo none of my favorite pet ;; esac break done
shift命令
一般用於函數或者腳本程序參數的處理,特別是參數多於10以上的時候,將所有參數變量向下移動一個位置,$2變成$1,$3變成$2,依次遞進,但是$0保持不變。
有趣的例子:
#!/bin/bash while [ “$1” != “” ] do echo $* shift done
(五)捕獲信號及其處理
鎖屏程序:
#!/bin/bash trap "nice_try" 2 3 15 TTY=`tty` nice_try() { echo -e "\nNice try,the terminal stays locked" } stty -echo echo -n "Enter your pasword to lock $TTY:" read PASSWORD clear echo -n "Enter your password to unlocked $TTY:" while : do read RESPONSE if [ "$RESPONSE" = "$PASSWORD" ];then echo "unlocking ..." break fi clear echo "wrong password and terminal is locked ..." echo -n "Enter your password to unlock $TTY:" done stty echostty -echo 是設置不回顯的。