Linux系統程式設計(15)——shell指令碼語法
Shell字串
字串是shell程式設計中最常用最有用的資料型別(除了數字和字串,也沒啥其它型別好用了),字串可以用單引號,也可以用雙引號,也可以不用引號。單雙引號的區別跟PHP類似。
單引號
str='this is a string'
單引號字串的限制:
單引號裡的任何字元都會原樣輸出,單引號字串中的變數是無效的;
單引號字串中不能出現單引號(對單引號使用轉義符後也不行)。
雙引號
your_name='qinjx'
str="Hello, I know your are\"$your_name\"! \n"
雙引號的優點:
雙引號裡可以有變數
雙引號裡可以出現轉義字元
拼接字串
your_name="qinjx"
greeting="hello,"$your_name" !"
greeting_1="hello, ${your_name}!"
echo $greeting $greeting_1
獲取字串長度
string="abcd"
echo ${#string} #輸出 4
提取子字串
string="alibaba is a greatcompany"
echo ${string:1:4} #輸出liba
查詢子字串
string="alibaba is a greatcompany"
echo `expr index "$string" is`
Shell陣列
Linux Shell在程式設計方面比Windows批處理強大很多,無論是在迴圈、運算。
bash支援一維陣列(不支援多維陣列),並且沒有限定陣列的大小。類似與C語言,陣列元素的下標由0開始編號。獲取陣列中的元素要利用下標,下標可以是整數或算術表示式,其值應大於或等於0。
定義陣列
在Shell中,用括號來表示陣列,陣列元素用“空格”符號分割開。定義陣列的一般形式為:
陣列名=(值1 值2 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
還可以單獨定義陣列的各個分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用連續的下標,而且下標的範圍沒有限制。
讀取陣列
讀取陣列元素值的一般格式是:
${陣列名[下標]}
例如:
valuen=${array_name[n]}
使用@符號可以獲取陣列中的所有元素,例如:
echo ${array_name[@]}
獲取陣列的長度
獲取陣列長度的方法與獲取字串長度的方法相同,例如:
# 取得陣列元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得陣列單個元素的長度
lengthn=${#array_name[n]}
Shelltest命令
Shell中的 test 命令用於檢查某個條件是否成立,它可以進行數值、字元和檔案三個方面的測試。
數值測試
引數 | 說明 |
-eq | 等於則為真 |
-ne | 不等於則為真 |
-gt | 大於則為真 |
-ge | 大於等於則為真 |
-lt | 小於則為真 |
-le | 小於等於則為真 |
例如:
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo 'The two numbers are equal!'
else
echo 'The two numbers are not equal!'
fi
輸出:
The two numbers are equal!
字串測試
引數 | 說明 |
= | 等於則為真 |
!= | 不相等則為真 |
-z 字串 | 字串長度偽則為真 |
-n 字串 | 字串長度不偽則為真 |
例如:
num1=100
num2=100
if test num1=num2
then
echo 'The two strings are equal!'
else
echo 'The two strings are not equal!'
fi
輸出:
The two strings are equal!
檔案測試
引數 | 說明 |
-e 檔名 | 如果檔案存在則為真 |
-r 檔名 | 如果檔案存在且可讀則為真 |
-w 檔名 | 如果檔案存在且可寫則為真 |
-x 檔名 | 如果檔案存在且可執行則為真 |
-s 檔名 | 如果檔案存在且至少有一個字元則為真 |
-d 檔名 | 如果檔案存在且為目錄則為真 |
-f 檔名 | 如果檔案存在且為普通檔案則為真 |
-c 檔名 | 如果檔案存在且為字元型特殊檔案則為真 |
-b 檔名 | 如果檔案存在且為塊特殊檔案則為真 |
例如:
cd /bin
if test -e ./bash
then
echo 'The file already exists!'
else
echo 'The file does not exists!'
fi
輸出:
The file already exists!
另外,Shell還提供了與( ! )、或( -o )、非( -a )三個邏輯操作符用於將測試條件連線起來,其優先順序為:“!”最高,“-a”次之,“-o”最低。例如:
cd /bin
if test -e ./notFile -o ./bash
then
echo 'One file exists at least!'
else
echo 'Both dose not exists!'
fi
輸出:
One file exists at least!
條件判斷語句if/then/elif/else/fi
和C語言類似,在Shell中用if、then、elif、else、fi這幾條命令實現分支控制。這種流程控制語句本質上也是由若干條Shell命令組成的,例如先前講過的
if [ -f ~/.bashrc ]; then
.~/.bashrc
fi其實是三條命令,if [ -f~/.bashrc ]是第一條,then . ~/.bashrc是第二條,fi是第三條。如果兩條命令寫在同一行則需要用;號隔開,一行只寫一條命令就不需要寫;號了,另外,then後面有換行,但這條命令沒寫完,Shell會自動續行,把下一行接在then後面當作一條命令處理。和[命令一樣,要注意命令和各引數之間必須用空格隔開。if命令的引數組成一條子命令,如果該子命令的Exit Status為0(表示真),則執行then後面的子命令,如果Exit Status非0(表示假),則執行elif、else或者fi後面的子命令。if後面的子命令通常是測試命令,但也可以是其它命令。Shell指令碼沒有{}括號,所以用fi表示if語句塊的結束。見下例:
#! /bin/sh
if [ -f /bin/bash ]
then echo "/bin/bash is a file"
else echo "/bin/bash is NOT afile"
fi
if :; then echo "always true";
fi:是一個特殊的命令,稱為空命令,該命令不做任何事,但Exit Status總是真。此外,也可以執行/bin/true或/bin/false得到真或假的Exit Status。再看一個例子:
#! /bin/sh
echo "Is it morning? Please answer yesor no."
read YES_OR_NO
if [ "$YES_OR_NO" ="yes" ]; then
echo "Good morning!"
elif [ "$YES_OR_NO" ="no" ]; then
echo "Good afternoon!"
else
echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
exit 1
fi
exit 0
上例中的read命令的作用是等待使用者輸入一行字串,將該字串存到一個Shell變數中。
此外,Shell還提供了&&和||語法,和C語言類似,具有Short-circuit特性,很多Shell指令碼喜歡寫成這樣:
test "$(whoami)" != 'root'&& (echo you are using a non-privileged account; exit 1)
&&相當於“if...then...”,而||相當於“ifnot...then...”。&&和||用於連線兩個命令,而上面講的-a和-o僅用於在測試表示式中連線兩個測試條件,要注意它們的區別,例如,
test "$VAR" -gt 1 -a"$VAR" -lt 3
和以下寫法是等價的
test "$VAR" -gt 1 && test"$VAR" -lt
case/esac語句
case命令可類比C語言的switch/case語句,esac表示case語句塊的結束。C語言的case只能匹配整型或字元型常量表示式,而Shell指令碼的case可以匹配字串和Wildcard,每個匹配分支可以有若干條命令,末尾必須以;;結束,執行時找到第一個匹配的分支並執行相應的命令,然後直接跳到esac之後,不需要像C語言一樣用break跳出。
#! /bin/sh
echo "Is it morning? Please answer yesor no."
read YES_OR_NO
case "$YES_OR_NO" in
yes|y|Yes|YES)
echo "Good Morning!";;
[nN]*)
echo "Good Afternoon!";;
*)
echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
exit 1;;
esac
exit 0
使用case語句的例子可以在系統服務的指令碼目錄/etc/init.d中找到。這個目錄下的指令碼大多具有這種形式(以/etc/apache2為例):
case $1 in
start)
...
;;
stop)
...
;;
reload| force-reload)
...
;;
restart)
...
*)
log_success_msg"Usage: /etc/init.d/apache2{start|stop|restart|reload|force-reload|start-htcacheclean|stop-htcacheclean}"
exit1
;;
esac啟動apache2服務的命令是
$ sudo /etc/init.d/apache2
start$1是一個特殊變數,在執行指令碼時自動取值為第一個命令列引數,也就是start,所以進入start)分支執行相關的命令。同理,命令列引數指定為stop、reload或restart可以進入其它分支執行停止服務、重新載入配置檔案或重新啟動服務的相關命令。
for/do/done語句
Shell指令碼的for迴圈結構和C語言很不一樣,它類似於某些程式語言的foreach迴圈。例如:
#! /bin/sh
for FRUIT in apple banana pear; do
echo "I like $FRUIT"
done
FRUIT是一個迴圈變數,第一次迴圈$FRUIT的取值是apple,第二次取值是banana,第三次取值是pear。再比如,要將當前目錄下的chap0、chap1、chap2等檔名改為chap0~、chap1~、chap2~等(按慣例,末尾有~字元的檔名錶示臨時檔案),這個命令可以這樣寫:
$ for FILENAME in chap?; do mv $FILENAME$FILENAME~; done
也可以這樣寫:
$ for FILENAME in `ls chap?`; do mv $FILENAME$FILENAME~; done5.5. while/do/done
while的用法和C語言類似。比如一個驗證密碼的指令碼:
#! /bin/sh
echo "Enter password:"
read TRY
while [ "$TRY" !="secret" ]; do
echo "Sorry, try again"
read TRY
done
下面的例子通過算術運算控制迴圈的次數:
#! /bin/sh
COUNTER=1
while [ "$COUNTER" -lt 10 ]; do
echo "Here we go again"
COUNTER=$(($COUNTER+1))
Done
Shell還有until迴圈,類似C語言的do...while迴圈。
Shell函式
shell允許將一組命令集或語句形成一個可用塊,這些塊稱為shell函式。
shell中函式的定義格式如下:
函式名(){
command1
command2
...
commandN
[return value ]
}
如果願意,可在函式名前加上關鍵字function,這取決於使用者。
function 函式名(){
command1
command2
...
commandN
[return value ]
}
函式返回值,可以顯示增加return語句;如果不加,則將最後一條命令執行結果作為返回值(一般為0,如果執行失敗則返回錯誤程式碼)。 return後跟數值(0-255)。
函式可以放在同一個檔案中作為一段程式碼,也可以放在只包含函式的單獨檔案中。函式不必包含很多語句或命令,甚至可以只包含一個echo語句,這取決於使用者。
下面的例子定義了一個函式並進行呼叫:
#!/bin/bash
demoFun(){
echo "This is your first shell function!"
}
echo "Function begin..."
hello
echo "Function end!"
輸出:
Function begin...
This is your first shell function!
Function end!
下面定義一個帶有return語句的函式:
#!/bin/bash
funWithReturn(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "The sum of two numbers is $?!"
輸出類似下面:
The function is to get the sum of twonumbers...
Input first number: 25
Input another number: 50
The two numbers are 25 and 50 !
The sum of two numbers is 75 !
函式返回值在呼叫該函式後通過 $? 來獲得。
注意:所有函式在使用前必須定義。這意味著必須將函式放在指令碼開始部分,直至shell直譯器首次發現它時,才可以使用。呼叫函式僅使用其函式名即可。
相關文章
- Linux系統程式設計(13)——Shell的基本語法Linux程式設計
- 史上最全shell指令碼程式設計語法上冊指令碼程式設計
- Linux Shell指令碼程式設計while語句案例Linux指令碼程式設計While
- 【指令碼】shell語法指令碼
- Linux作業系統的Shell程式設計指令碼欣賞(轉)Linux作業系統程式設計指令碼
- Linux Shell程式設計(3)——執行shell指令碼Linux程式設計指令碼
- 【學習】Linux Shell指令碼程式設計Linux指令碼程式設計
- Linux Shell指令碼程式設計-基礎1Linux指令碼程式設計
- Shell 指令碼程式設計陷阱指令碼程式設計
- shell指令碼程式設計筆記指令碼程式設計筆記
- 7.shell指令碼程式設計指令碼程式設計
- 初識shell指令碼程式設計指令碼程式設計
- shell指令碼程式設計基礎指令碼程式設計
- 使用 Shell 指令碼監控 Linux 系統程式資源指令碼Linux
- Linux shell程式設計(一)shell指令碼中的變數詳解Linux程式設計指令碼變數
- 利用shell指令碼統計程式碼行數指令碼
- Linux Shell程式設計(15)——操作字串Linux程式設計字串
- Shell指令碼程式設計初體驗指令碼程式設計
- BASH Shell的指令碼程式設計(轉)指令碼程式設計
- Linux作業系統之Shell程式設計Linux作業系統程式設計
- Linux系統程式設計(12)——shell基礎Linux程式設計
- Linux Bash Shell學習(七):shell程式設計基礎——執行Shell指令碼、functionLinux程式設計指令碼Function
- Shell程式設計-01-Shell指令碼初步入門程式設計指令碼
- LINUX Shell指令碼程式設計例項詳解(一)上Linux指令碼程式設計
- Linux程式設計:將PHP作為Shell指令碼使用(轉)Linux程式設計PHP指令碼
- 高階bash/shell指令碼程式設計指南指令碼程式設計
- 記錄shell指令碼程式設計相關指令碼程式設計
- 《Linux命令列與shell指令碼程式設計大全》第五章理解shellLinux命令列指令碼程式設計
- shell高效程式設計:shell指令碼從未如此美麗程式設計指令碼
- Linux命令列與shell指令碼程式設計入門經驗Linux命令列指令碼程式設計
- Linux_day06_01_Shell指令碼程式設計_Bash基礎Linux指令碼程式設計
- 好程式設計師Linux雲端計算教程分享Shell指令碼面試題程式設計師Linux指令碼面試題
- shell 指令碼寫法:指令碼
- 10分鐘入門Shell指令碼程式設計指令碼程式設計
- Shell指令碼程式設計30分鐘入門指令碼程式設計
- Linux系統程式設計(14)——shell常用命令Linux程式設計
- Shell 指令碼語句指令碼
- Shell指令碼語言有什麼優勢?linux系統學習步驟指令碼Linux