標籤:shell
印象中,一直覺得只要多掌握linux命令,自然對於寫shell指令碼不會陌生.這句話對也不對.前半句對了,的確是要多掌握linux命令,這樣才能寫出使用高效的指令碼,但是後半句不對.要寫出shell指令碼,還需要掌握shell的內部命令,流程式控制制,以及重新導向等.
最近系統的學習了一些shell的入門,有了很多新的認識,積累如下.
1. 變數:
shell中,變數的使用並不需要聲明,可以直接使用,而且沒有類型的限制,同樣一個變數,不同的操作,決定變數不同的類型,比如 [ $a = $b ],這裡的變數a和b,是字串.但是同樣是他倆,[ $a -gt $b ],在這裡他倆就成了數字.當然這隻是特殊情況,如果a的值並不是數字,是會報錯的.
同時需要明確,linux大小寫敏感,shell自然也不例外.
另外需要注意的就是變數拓展,即聲明一個a變數,$ab並不會被識別成a的值接上b,而應該${a}b.另外一種非變數拓展的方式是"$a"b
環境變數,用來改變shell的行為的一種特殊變數.常用的有
$HOME 目前使用者的家路徑
$PATH 當前系統的搜尋命令的路徑
$PS1 命令提示字元
$PS2 二級提示符,即當輸入的命令沒有輸入完全的時候的提示符
$IFS 域分隔字元 預設是空格,定位字元,分行符號
$0 shell指令碼的名字
$# shell指令碼參數的個數
$$ shell指令碼的進程號
$1...$n shell指令碼的參數
$* shell指令碼參數列表,受域分隔字元的影響.
[email protected] shell指令碼參數列表,不受域分隔字元的影響.
例如:
2. 條件判斷
test 和 [ ] , 對於判斷而言,二者作用是完全一樣的,可以使用test就可以用 [ ].
目前判斷大致可以分為三種,
字串的判斷
[ $string1 = $string2 ] 字串相等.這裡需要注意空格的使用.
[ $string1 != $string2 ] 字串不想等
[ -n $string1 ] 字串不為空白
[ -z $string1 ] 字串為空白
數字比較
[ $a -eq $b ] a和b相等
[ $a -ne $b ] a和b不相等
[ $a -gt $b ] a大於b
[ $a -ge $b ] a大於等於b
[ $a -lt $b ] a小於b
[ $a -le $b ] a小於等於b
[ ! a ] a為假則運算式為真,注意空格的使用.
檔案判斷
-f 是否是普通檔案
-e 是否存在,但是存在可移植性問題.並不是每個版本的shell都支援這個選項
-d 是否是目錄
-b 是否是塊檔案.
-s 是否大小不為0
-r 是否可讀
-w 是否可寫
-x 是否可執行
以上為是,則為真.
3. 流程式控制制 (if for while until case)
if 測試某個結果,根據結果的不同做出不同的工作.
常見的if控制結構:
if [ condition ]
then
command
elif [ condition ]
then
command
else
command
fi
舉個例子:
#!/bin/bashecho what day is it today?read dayif [ $day = sateday ] || [ $day = sunday ]then echo oh good!!!else echo oh god...fi
這個小例子裡面還包括了一個知識點,即命令列表的知識,簡單的拓展一下.
command1 && command2 && command3 && ..... 此shell語句中,從左往右順序執行,遇到第一個返回false的命令則不再繼續執行.
command1 || command2 || command3 || ..... 此shell語句從左往右順序執行,遇到第一個執行成功的命令就不再繼續執行.
for 迴圈執行執行某個命令塊.
用法如下:
for 變數 in 範圍
do
something
done
範圍可以通過大括弧指定,也可以是一個命令或者一個變數.如樣本:
#!/bin/bash echo test for 1 for i in {a,b,c} do echo -e "\t$i" done echo test for 1 end echo test for 2 for i in {d..g} do echo -e "\t$i" done echo test for 2 end echo test for 3 for i in `seq 10` do echo -e "\t$i" done echo test for 3 end echo test for 4 filelist=$(ls) for i in $filelist do echo -e "\t$i" done echo test for 4 end
while 迴圈執行一段代碼塊但是和for不一樣的是,while後面跟的是一個條件限定,而不是一個範圍.while迴圈執行直到條件為假.
基本用法如下:
while condition
do
something
done
一般可以作為condition的有很多,if裡面適用的在這裡也幾乎適用.如下:
#!/bin/bashwhile read i do echo $idone < for.shecho "this is a test" | while read i do echo $idone
一定要注意shell中的真假只能用true(:)和false來表示.如果你用0或者1,那就錯了.對於shell而言,無論0和1在條件判斷中,都是真.而在上面的這個例子中,檔案為eof代表條件為假.
until 迴圈執行一段程式碼片段.和while相反,until迴圈執行直到條件為真.
用法和while類似.
until condition
do
something
done
慚愧,我一時竟然想不到一個可以使用的例子.抄一段:
#!/bin/bashuntil who | grep "$1" > /dev/nulldo sleep 60doneecho -e "\a"echo "$1 logged"
這個指令碼的意思是,指定一個參數,也就是$1.如果$1代表的使用者登陸過系統,就警示並且列印資訊然後退出.否則就迴圈等待.
case 分支語句,和if有點類似我想,看看用法吧.
case 變數 in
pattern1) something ;;
pattern2) something ;;
esac
還是通過一個執行個體來看看他是怎麼使用的吧.
#!/bin/bashecho will you marry me?read choicecase $choice in Y|y|[Yy][Ee][Ss]) echo yes, i will ;; [Nn]*) echo you are good man,please don\'t let me hurt ;; *) echo ni chi fan mei you ;;esac
case的語句可以選擇的幾種方式,上面都列了出來.
Y|y|[Yy][Ee][Ss] #這段的意思是,無論輸入Y或者y或者YEs或者yeS都會輸出yes,i will而*)的意思相當於default.<span style="font-size:18px;">4. 函數</span>
shell的函數很簡單.不需要參數,不需要返回值.只需要這樣
func()
{
do something
}
但是這個函數看起來不是和廢物一樣嘛,接受不了參數,又沒有辦法輸出結果.肯定不是啊,shell的函數可以理解成一個指令碼內的指令碼,也就是說他傳遞參數的方式和shell指令碼接收參數的方式類似.$#表示函數的參數個數,[email protected]函數的參數列表$*也是參數列表$1$2是函數的第1或者2個參數.
#!/bin/bashtest_master(){ if test $# -ne 2 then echo please input 2 parameter exit fi echo who is the master in your home? for i in `seq $#` do eval res='$'$i if [ $res != "alai" ] then echo $res fi done}test_master alai jingjing
5. 部分命令
本段主要涉及的都是內建命令.
break 用來跳出迴圈,為內建命令.可以在後面跟一個數字表示跳出多少層迴圈.一般不建議這麼使用.容易把代碼邏輯搞亂.
:命令 此命令為空白命令.永遠表示true,但是運行速度要快於true(書本上這麼說的,我反正察覺不到),很早之前的shell習慣性的用 : command 的方式作為指令碼注釋.現在統一採用#
continue 跳大下一次迴圈,統一可以跟一個數字表示繼續第n此迴圈,也不建議這麼使用.
. 命令 表示在當前shell執行命令.一般我們用的./的方式,會產生一個子進程然後執行指令碼,使用這個命令,直接在當前的進程執行命令.
echo 列印命令.不解釋啦.
eval 這個命令很有趣,允許對參數進行求值.上面講解函數的時候也有它的用法.這裡不多說啦.不要忘記單引號哈.
exit n 以退出碼n來結束指令碼的運行.目前而言0表示運行成功.其它表示運行失敗.在指令碼中多運用這個命令是個很好的習慣.
export 將其後的變數匯入到子shell中.
expr 將參數作為運算式求值相當於$[ ] 用法 res=`expr 1+2`
let 作用和expr是一樣的,用法有差異 let a=1+1 注意別有空格.這個應該不是內建的
大致就總結這麼多吧.希望能夠對同學們入門shell有協助.
shell學習入門