這是作者早期的 Shell 編程學(xué)習(xí)筆記,主要包括 Shell 概述、 Shell 變量、位置參數(shù)、特殊符號、別名、各種控制語句、函數(shù)等 Shell 編程知識。
要想系統(tǒng)地學(xué) Shell,應(yīng)該找些較系統(tǒng)的資料,例如:《Shell 編程范例》和《鳥哥學(xué)習(xí)Shell Scripts》。
$ bash < ex1
可以讀入 ex1
中的程序,并執(zhí)行
其一般形式是:
$ bash 腳本名 [參數(shù)]
例如:
$ bash ex2 /usr/meng /usr/zhang
其執(zhí)行過程與上一種方式一樣,但這種方式的好處是能在腳本名后面帶有參數(shù),從而將參數(shù)值傳遞給程序中的命令,使一個 Shell 腳本可以處理多種情況,就如同函數(shù)調(diào)用時可根據(jù)具體問題傳遞相應(yīng)的實參。
如果以當(dāng)前 Shell (以 ·
表示)執(zhí)行一個 Shell 腳本,則可以使用如下簡便形式:
$ · ex3[參數(shù)]
將 Shell 腳本的權(quán)限設(shè)置為可執(zhí)行,然后在提示符下直接執(zhí)行它。
具體辦法:
$ chmod a+x ex4
$ ./ex4
這個要求在 Shell 腳本的開頭指明執(zhí)行該腳本的具體 Shell,例如 /bin/bash
:
#!/bin/bash
Shell 接收用戶輸入的命令(腳本名),并進行分析。如果文件被標記為可執(zhí)行,但不是被編譯過的程序,Shell 就認為它是一個 Shell 腳本。 Shell 將讀取其中的內(nèi)容,并加以解釋執(zhí)行。所以,從用戶的觀點看,執(zhí)行 Shell 腳本的方式與執(zhí)行一般的可執(zhí)行文件的方式相似。
因此,用戶開發(fā)的 Shell 腳本可以駐留在命令搜索路徑的目錄之下(通常是 /bin
、/usr/bin
等),像普通命令一樣使用。這樣,也就開發(fā)出自己的新命令。如果打算反復(fù)使用編好的 Shell 腳本,那么采用這種方式就比較方便。
可以將一個命令的執(zhí)行結(jié)果賦值給變量。有兩種形式的命令替換:一種是使用倒引號引用命令,其一般形式是: 命令表
。
例如:將當(dāng)前工作目錄的全路徑名存放到變量dir中,輸入以下命令行:
$ dir=`pwd`
另一種形式是:$(命令表)
。上面的命令行也可以改寫為:
$ dir=$(pwd)
Bash
只提供一維數(shù)組,并且沒有限定數(shù)組的大小。類似與 C 語言,數(shù)組元素的下標由 0 開始編號。獲取數(shù)組中的元素要利用下標。下標可以是整數(shù)或算術(shù)表達式,其值應(yīng)大于或等于 0 。用戶可以使用賦值語句對數(shù)組變量賦值。
對數(shù)組元素賦值的一般形式是:數(shù)組名[下標]=值
,例如:
$ city[0]=Beijing
$ city[1]=Shanghai
$ city[2]=Tianjin
也可以用 declare
命令顯式聲明一個數(shù)組,一般形式是:
$ declare -a 數(shù)組名
讀取數(shù)組元素值的一般格式是: ${數(shù)組名[下標]}
,例如:
$ echo ${city[0]}
Beijing
一個數(shù)組的各個元素可以利用上述方式一個元素一個元素地賦值,也可以組合賦值。定義一個數(shù)組并為其賦初值的一般形式是:
數(shù)組名=(值1 值2 ... 值n)
其中,各個值之間以空格分開。例如:
$ A=(this is an example of shell script)
$ echo ${A[0]} ${A[2]} ${A[3]} ${A[6]}
this an example script
$ echo ${A[8]}
由于值表中初值共有 7 個,所以 A
的元素個數(shù)也是 7 。 A[8]
超出了已賦值的數(shù)組 A
的范圍,就認為它是一個新元素,由于預(yù)先沒有賦值,所以它的值是空串。
若沒有給出數(shù)組元素的下標,則數(shù)組名表示下標為 0 的數(shù)組元素,如 city
就等價于 city[0]
。
使用 *
或 @
做下標,則會以數(shù)組中所有元素取代。
$ echo ${A[*]}
this is an example of shell script
$ echo ${#A[*]}
7
假如要編寫一個 Shell 來求兩個數(shù)的和,可以怎么實現(xiàn)呢?為了介紹參數(shù)傳遞的用法,編寫這樣一個腳本:
$ cat > add
let sum=$1+$2
echo $sum
保存后,執(zhí)行一下:
$ chmod a+x ./add
$ ./add 5 10
15
可以看出 5 和 10 分別傳給了 $1
和 $2
,這是 Shell 自己預(yù)設(shè)的參數(shù)順序,其實也可以先定義好變量,然后傳遞進去。
例如,修改上述腳本得到:
let sum=$X+$Y
echo $sum
再次執(zhí)行:
$ X=5 Y=10 ./add
15
可以發(fā)現(xiàn),同樣可以得到正確結(jié)果。
export一個環(huán)境變量:
$ export opid=True
這樣子就可以,如果要登陸后都生效,可以直接添加到 /etc/profile
或者 ~/.bashrc
里頭。
可以通過 read
來讀取變量值,例如,來等待用戶輸入一個值并且顯示出來:
$ read -p "請輸入一個值 : " input ; echo "你輸入了一個值為 :" $input
請輸入一個值 : 21500
你輸入了一個值為 : 21500
有些重要的 Shell 變量,賦值后不應(yīng)該修改,那么可設(shè)置它為 readonly
:
$ oracle_home=/usr/oracle7/bin
$ readonly oracle_home
語法:test 表達式
如果表達式為真,則返回真,否則,返回假。
先給出數(shù)值比較時常見的比較符:
-eg =;-ne !=;-gt >;-ge >=;-lt <;-le <=
$ test var1 -gt var2
文件的可讀、可寫、可執(zhí)行,是否為普通文件,是否為目錄分別對應(yīng):
-r; -w; -x; -f; -d
$ test -r filename
串的長度為零:
-z
; 非零:-n
,如:
$ test -z s1
如果串 s1
長度為零,返回真。
相等
"s1"="s2"
; 不相等"s1"!="s2"
還有一種比較串的方法(可以按字典序來比較):
$ if [[ 'abcde' < 'abcdf' ]]; then echo "yeah,果然是誒"; fi
yeah,果然是誒
可用該命令進行的運算有:
算術(shù)運算:
+ - * / %
;邏輯運算:= ! < <= > >=
如:
$ i=5;expr $i+5
另外,bc
是一個命令行計算器,可以進行一些算術(shù)計算。
if
命令舉例:如果第一個參數(shù)是一個普通文件名,那么分頁打印該文件;否則,如果它為目錄名,則進入該目錄并打印該目錄下的所有文件,如果也不是目錄,那么提示相關(guān)信息。
if test -f $1
then
pr $1>/dev/lp0
elif
test-d $1
then
(cd $1;pr *>/dev/lp0)
else
echo $1 is neither a file nor a directory
fi
case
命令是一個基于模式匹配的多路分支命令,下面將根據(jù)用戶鍵盤輸入情況決定下一步將執(zhí)行那一組命令。
while [ $reply!="y" ] && [ $reply!="Y" ] #下面將學(xué)習(xí)的循環(huán)語句
do
echo "\nAre you want to continue?(Y/N)\c"
read reply #讀取鍵盤
case $replay in
(y|Y) break;; #退出循環(huán)
(n|N) echo "\n\nTerminating\n"
exit 0;;
*) echo "\n\nPlease answer y or n"
continue; #直接返回內(nèi)層循環(huán)開始出繼續(xù)
esac
done
語法:
while/until 命令表1
do
命令表2
done
區(qū)別是,前者執(zhí)行命令表 1 后,如果退出狀態(tài)為零,那么執(zhí)行 do
后面的命令表 2,然后回到起始處,而后者執(zhí)行命令表 1 后,如果退出狀態(tài)非零,才執(zhí)行類似操作。例子同上。
語法:
for 變量名 in 字符串表
do
命令表
done
舉例:
FILE="test1.c myfile1.f pccn.h"
for i in $FILE
do
cd ./tmp
cp $i $i.old
echo "$i copied"
done
現(xiàn)在來看看 Shell 里頭的函數(shù)用法,先看個例子:寫一個函數(shù),然后調(diào)用它顯示 Hello, World!
$ cat > show
# 函數(shù)定義
function show
{
echo $1$2;
}
H="Hello,"
W="World!"
# 調(diào)用函數(shù),并傳給兩個參數(shù)H和W
show $H $W
演示:
$ chmod 770 show
$./show
Hello,World!
看出什么蹊蹺了嗎?
$ show $H $W
咱們可以直接在函數(shù)名后面跟實參。
實參順序?qū)?yīng)“虛參”的 $1,$2,$3
……
注意:假如要傳入一個參數(shù),如果這個參數(shù)中間帶空格,怎么辦? 先試試看。
來顯示 Hello World
(兩個單詞之間有個空格)
function show
{
echo $1
}
HW="Hello World"
show "$HW"
如果直接 show $HW
,肯定不行,因為 $1
只接受到了 Hello
,所以結(jié)果只顯示 Hello
,原因是字符串變量必須用 "
包含起來。
感興趣的話繼續(xù)學(xué)習(xí)吧!
還有好多強大的東西等著呢,比如 cut
,expr
,sed
,awk
等等。
更多建議: