在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ shell 腳本
初步進(jìn)入 linux 世界
Linux 系統(tǒng)的遠(yuǎn)程登錄
配置 Tomcat
配置 samba 服務(wù)器
LNMP 環(huán)境搭建
配置 FTP 服務(wù)
linux 系統(tǒng)用戶以及用戶組管理
正則表達(dá)式
LAMP環(huán)境搭建
安裝 RPM 包或者安裝源碼包
NFS 服務(wù)配置
文檔的壓縮與打包
Linux 操作系統(tǒng)的安裝
配置 squid 服務(wù)
Linux 文件與目錄管理
Linux 磁盤管理
學(xué)會使用簡單的 MySQL 操作
關(guān)于 Linux 的歷史
學(xué)習(xí) shell 腳本之前的基礎(chǔ)知識
圖形界面還是命令窗口
文本編輯工具 vim
shell 腳本
使用 Nagios 搭建監(jiān)控服務(wù)器
linux 系統(tǒng)日常管理

shell 腳本

終于到shell 腳本這章了,在以前筆者賣了好多關(guān)子說shell腳本怎么怎么重要,確實(shí)shell腳本在linux系統(tǒng)管理員的運(yùn)維工作中非常非常重要。下面筆者就帶你正式進(jìn)入shell腳本的世界吧。

到現(xiàn)在為止,你明白什么是shell腳本嗎?如果明白最好了,不明白也沒有關(guān)系,相信隨著學(xué)習(xí)的深入你就會越來越了解到底什么是shell腳本。首先它是一個腳本,并不能作為正式的編程語言。因?yàn)槭桥茉?/span>linuxshell中,所以叫shell腳本。說白了,shell腳本就是一些命令的集合。舉個例子,我想實(shí)現(xiàn)這樣的操作:1)進(jìn)入到/tmp/目錄;2)列出當(dāng)前目錄中所有的文件名;3)把所有當(dāng)前的文件拷貝到/root/目錄下;4)刪除當(dāng)前目錄下所有的文件。簡單的4步在shell窗口中需要你敲4次命令,按4次回車。這樣是不是很麻煩?當(dāng)然這4步操作非常簡單,如果是更加復(fù)雜的命令設(shè)置需要幾十次操作呢?那樣的話一次一次敲鍵盤會很麻煩。所以不妨把所有的操作都記錄到一個文檔中,然后去調(diào)用文檔中的命令,這樣一步操作就可以完成其實(shí)這個文檔呢就是shell腳本了,只是這個shell腳本有它特殊的格式

Shell腳本能幫助我們很方便的去管理服務(wù)器,因?yàn)槲覀兛梢灾付ㄒ粋€任務(wù)計劃定時去執(zhí)行某一個shell腳本實(shí)現(xiàn)我們想要需求。這對于linux系統(tǒng)管理員來說是一件非常值得自豪的事情現(xiàn)在的139郵箱很好用,發(fā)郵件的同時還可以發(fā)一條郵件通知的短信給用戶,利用這點(diǎn),我們就可以在我們的linux服務(wù)器上部署監(jiān)控的shell腳本,比如網(wǎng)卡流量有異常了或者服務(wù)器web服務(wù)器停止了就可以發(fā)一封郵件給管理員,同時發(fā)送給管理員一個報警短信這樣可以讓我們及時的知道服務(wù)器出問題了。

有一個問題需要約定一下,凡是自定義的腳本建議放到/usr/local/sbin/目錄下,這樣做的目的是,一來可以更好的管理文檔;二來以后接管你的管理員都知道自定義腳本放在哪里,方便維護(hù)。

shell腳本的基本結(jié)構(gòu)以及如何執(zhí)行

http://wiki.jikexueyuan.com/project/linux/images/14_1.png.jpg" alt="14_1.png.jpg" />

Shell腳本通常都是以.sh 為后綴名的,這個并不是說不帶.sh這個腳本就不能執(zhí)行,只是大家的一個習(xí)慣而已所以,以后你發(fā)現(xiàn)了.sh為后綴的文件那么它一定會是一個shell腳本了。test.sh中第一行一定是 “#! /bin/bash” 它代表的意思是,該文件使用的是bash語法如果不設(shè)置該行,那么你的shell腳本就不能被執(zhí)行。’#’表示注釋,在前面講過的。后面跟一些該腳本的相關(guān)注釋內(nèi)容以及作者和創(chuàng)建日期或者版本等等。當(dāng)然這些注釋并非必須的,如果你懶的很,可以省略掉,但是筆者不建議省略。因?yàn)殡S著你工作時間的增加,你寫的shell腳本也會越來越多,如果有一天你回頭查看你寫的某個腳本時,很有可能忘記該腳本是用來干什么的以及什么時候?qū)懙?/span>。所以寫上注釋是有必要的。另外系統(tǒng)管理員并非你一個,如果是其他管理員查看你的腳本,他看不懂豈不是很郁悶。該腳本再往下面則為要運(yùn)行的命令了

http://wiki.jikexueyuan.com/project/linux/images/14_7.png.jpg" alt="14_7.png.jpg" />

Shell腳本的執(zhí)行很簡單,直接”sh filename “ 即可,另外你還可以這樣執(zhí)行

http://wiki.jikexueyuan.com/project/linux/images/14_8.png.jpg" alt="14_8.png.jpg" />

默認(rèn)我們用vim編輯的文檔是不帶有執(zhí)行權(quán)限的,所以需要加一個執(zhí)行權(quán)限,那樣就可以直接使用’./filename’ 執(zhí)行這個腳本了另外使用sh命令去執(zhí)行一個shell腳本的時候是可以加-x選項(xiàng)來查看這個腳本執(zhí)行過程的,這樣有利于我們調(diào)試這個腳本哪里出了問題。

http://wiki.jikexueyuan.com/project/linux/images/14_9.png.jpg" alt="14_9.png.jpg" />

shell腳本中用到了’date’這個命令,它的作用就是用來打印當(dāng)前系統(tǒng)的時間。其實(shí)在shell腳本中date使用率非常高有幾個選項(xiàng)筆者常常在shell腳本中用到:

http://wiki.jikexueyuan.com/project/linux/images/14_10.png.jpg" alt="14_10.png.jpg" />

%Y表示年,%m表示月,%d表示日期,%H表示小時,%M表示分鐘,%S表示秒

http://wiki.jikexueyuan.com/project/linux/images/14_11.png.jpg" alt="14_11.png.jpg" />

注意%y%Y的區(qū)別。

http://wiki.jikexueyuan.com/project/linux/images/14_21.png.jpg" alt="14_21.png.jpg" />

-d 選項(xiàng)也是經(jīng)常要用到的,它可以打印n天前或者n天后的日期,當(dāng)然也可以打印n個月/年前或者后的日期。

http://wiki.jikexueyuan.com/project/linux/images/14_22.png.jpg" alt="14_22.png.jpg" />

另外星期幾也是常用的

http://wiki.jikexueyuan.com/project/linux/images/14_23.png.jpg" alt="14_23.png.jpg" />

【shell腳本中的變量

shell腳本中使用變量顯得我們的腳本更加專業(yè)更像是一門語言,開個玩笑,變量的作用當(dāng)然不是為了專業(yè)如果你寫了一個長達(dá)1000行的shell腳本,并且腳本中出現(xiàn)了某一個命令或者路徑幾百次。突然你覺得路徑不對想換一下,那豈不是要更改幾百次?你固然可以使用批量替換的命令,但是也是很麻煩,并且腳本顯得臃腫了很多。變量的作用就是用來解決這個問題的。

http://wiki.jikexueyuan.com/project/linux/images/14_24.png.jpg" alt="14_24.png.jpg" />

test2.sh中使用到了反引號,你是否還記得它的作用?’d’’d1’在腳本中作為變量出現(xiàn),定義變量的格式為 變量名=變量的值”。當(dāng)在腳本中引用變量時需要加上’$’符號,這跟前面講的在shell中自定義變量是一致的。下面看看腳本執(zhí)行結(jié)果吧。

http://wiki.jikexueyuan.com/project/linux/images/14_25.png.jpg" alt="14_25.png.jpg" />

下面我們用shell計算兩個數(shù)的和。

http://wiki.jikexueyuan.com/project/linux/images/14_26.png.jpg" alt="14_26.png.jpg" />

數(shù)學(xué)計算要用’[ ]’括起來并且外頭要帶一個’$’。腳本結(jié)果為:

http://wiki.jikexueyuan.com/project/linux/images/14_27.png.jpg" alt="14_27.png.jpg" />

Shell腳本還可以和用戶交互。

http://wiki.jikexueyuan.com/project/linux/images/14_28.png.jpg" alt="14_28.png.jpg" />

這就用到了read命令了,它可以從標(biāo)準(zhǔn)輸入獲得變量的值,后跟變量名?!眗ead x”表示x變量的值需要用戶通過鍵盤輸入得到。腳本執(zhí)行過程如下:

http://wiki.jikexueyuan.com/project/linux/images/14_29.png.jpg" alt="14_29.png.jpg" />

我們不妨加上-x選項(xiàng)再來看看這個執(zhí)行過程:

http://wiki.jikexueyuan.com/project/linux/images/14_44.png.jpg" alt="14_44.png.jpg" />

test4.sh中還有更加簡潔的方式。

http://wiki.jikexueyuan.com/project/linux/images/14_45.png.jpg" alt="14_45.png.jpg" />

read -p 選項(xiàng)類似echo的作用。執(zhí)行如下:

http://wiki.jikexueyuan.com/project/linux/images/14_46.png.jpg" alt="14_46.png.jpg" />

你有沒有用過這樣的命令”/etc/init.d/iptables restart “ 前面的/etc/init.d/iptables 文件其實(shí)就是一個shell腳本,為什么后面可以跟一個”restart”? 這里就涉及到了shell腳本的預(yù)設(shè)變量實(shí)際上,shell腳本在執(zhí)行的時候后邊是可以跟變量的,而且還可以跟多個不妨筆者寫一個腳本,你就會明白了

http://wiki.jikexueyuan.com/project/linux/images/14_47.png.jpg" alt="14_47.png.jpg" />

執(zhí)行過程如下:

http://wiki.jikexueyuan.com/project/linux/images/14_48.png.jpg" alt="14_48.png.jpg" />

在腳本中,你會不會奇怪,哪里來的$1$2,這其實(shí)就是shell腳本的預(yù)設(shè)變量,其中$1的值就是在執(zhí)行的時候輸入的1,而$2的值就是執(zhí)行的時候輸入的$2,當(dāng)然一個shell腳本的預(yù)設(shè)變量是沒有限制的,這回你明白了吧。另外還有一個$0,不過它代表的是腳本本身的名字。不妨把腳本修改一下。

http://wiki.jikexueyuan.com/project/linux/images/14_49.png.jpg" alt="14_49.png.jpg" />

執(zhí)行結(jié)果想必你也猜到了吧。

http://wiki.jikexueyuan.com/project/linux/images/14_50.png.jpg" alt="14_50.png.jpg" />

【shell腳本中的邏輯判斷

如果你學(xué)過C或者其他語言,相信你不會對if 陌生,在shell腳本中我們同樣可以使用if邏輯判斷。shellif判斷的基本語法為:

1)不帶else

if 判斷語句; then

command

fi

http://wiki.jikexueyuan.com/project/linux/images/14_51.png.jpg" alt="14_51.png.jpg" />

if1.sh中出現(xiàn)了 ((a<60))這樣的形式,這是shell腳本中特有的格式,用一個小括號或者不用都會報錯,請記住這個格式,即可執(zhí)行結(jié)果為:

http://wiki.jikexueyuan.com/project/linux/images/14_52.png.jpg" alt="14_52.png.jpg" />

2)帶有else

if 判斷語句 ; then

command

else

command

fi

http://wiki.jikexueyuan.com/project/linux/images/14_53.png.jpg" alt="14_53.png.jpg" />

執(zhí)行結(jié)果為:

http://wiki.jikexueyuan.com/project/linux/images/14_54.png.jpg" alt="14_54.png.jpg" />

3)帶有elif

if 判斷語句一 ; then

command

elif 判斷語句二; then

command

else

command

fi

http://wiki.jikexueyuan.com/project/linux/images/14_55.png.jpg" alt="14_55.png.jpg" />

這里的 && 表示并且的意思,當(dāng)然你也可以使用 || 表示或者,執(zhí)行結(jié)果:

http://wiki.jikexueyuan.com/project/linux/images/14_56.png.jpg" alt="14_56.png.jpg" />

以上只是簡單的介紹了if語句的結(jié)構(gòu)。在判斷數(shù)值大小除了可以用”(( ))”的形式外,還可以使用”[ ]”。但是就不能使用>, < , = 這樣的符號了,要使用 -lt (小于),-gt (大于),-le (小于等于),-ge (大于等于),-eq (等于),-ne (不等于)。

http://wiki.jikexueyuan.com/project/linux/images/14_57.png.jpg" alt="14_57.png.jpg" />

再看看if中使用 && ||的情況

http://wiki.jikexueyuan.com/project/linux/images/14_71.png.jpg" alt="14_71.png.jpg" />

shell 腳本中if還經(jīng)常判斷關(guān)于檔案屬性,比如判斷是普通文件還是目錄,判斷文件是否有讀寫執(zhí)行權(quán)限等。常用的也就幾個選項(xiàng):

-e :判斷文件或目錄是否存在

-d :判斷是不是目錄,并是否存在

-f :判斷是否是普通文件,并存在

-r :判斷文檔是否有讀權(quán)限

-w :判斷是否有寫權(quán)限

-x :判斷是否可執(zhí)行

使用if判斷時,具體格式為: if [ -e filename ] ; then

http://wiki.jikexueyuan.com/project/linux/images/14_72.png.jpg" alt="14_72.png.jpg" />

shell 腳本中,除了用if來判斷邏輯外,還有一種常用的方式,那就是case。具體格式為:

case 變量 in

value1)

command

;;

value2)

command

;;

value3)

command

;;

*)

command

;;

esac

上面的結(jié)構(gòu)中,不限制value的個數(shù),*則代表除了上面的value外的其他值。下面筆者寫一個判斷輸入數(shù)值是奇數(shù)或者偶數(shù)的腳本。

http://wiki.jikexueyuan.com/project/linux/images/14_73.png.jpg" alt="14_73.png.jpg" />

$a 的值或?yàn)?/span>1或?yàn)?/span>0,執(zhí)行結(jié)果為:

http://wiki.jikexueyuan.com/project/linux/images/14_74.png.jpg" alt="14_74.png.jpg" />

也可以看一下執(zhí)行過程:

http://wiki.jikexueyuan.com/project/linux/images/14_75.png.jpg" alt="14_75.png.jpg" />

case腳本常用于編寫系統(tǒng)服務(wù)的啟動腳本,例如/etc/init.d/iptables中就用到了,你不妨去查看一下

【shell腳本中的循環(huán)

Shell腳本中也算是一門簡易的編程語言了,當(dāng)然循環(huán)是不能缺少的。常用到的循環(huán)有for循環(huán)和while循環(huán)。下面就分別介紹一下兩種循環(huán)的結(jié)構(gòu)。

http://wiki.jikexueyuan.com/project/linux/images/14_76.png.jpg" alt="14_76.png.jpg" />

腳本中的seq 1 5 表示從15的一個序列。你可以直接運(yùn)行這個命令試下腳本執(zhí)行結(jié)果為:

http://wiki.jikexueyuan.com/project/linux/images/14_77.png.jpg" alt="14_77.png.jpg" />

通過這個腳本就可以看到for循環(huán)的基本結(jié)構(gòu)

for 變量名 in 循環(huán)的條件; do

command

done

http://wiki.jikexueyuan.com/project/linux/images/14_78.png.jpg" alt="14_78.png.jpg" />

循環(huán)的條件那一部分也可以寫成這樣的形式,中間用空格隔開即可你也可以試試,for i in ls; do echo $i; done for i in cat test.txt; do echo $i; done

http://wiki.jikexueyuan.com/project/linux/images/14_79.png.jpg" alt="14_79.png.jpg" />

再來看看這個while循環(huán),基本格式為:

while 條件; do

command

done

腳本的執(zhí)行結(jié)果為:

http://wiki.jikexueyuan.com/project/linux/images/14_80.png.jpg" alt="14_80.png.jpg" />

另外你可以把循環(huán)條件忽略掉,筆者常常這樣寫監(jiān)控腳本。

while :; do

command

done

【shell腳本中的函數(shù)

如果你學(xué)過開發(fā),肯定知道函數(shù)的作用如果你是剛剛接觸到這個概念的話,也沒有關(guān)系,其實(shí)很好理解的。函數(shù)就是把一段代碼整理到了一個小單元中,并給這個小單元起一個名字,當(dāng)用到這段代碼時直接調(diào)用這個小單元的名字即可。有時候腳本中的某段代總是重復(fù)使用,如果寫成函數(shù),每次用到時直接用函數(shù)名代替即可,這樣就節(jié)省了時間還節(jié)省了空間。

http://wiki.jikexueyuan.com/project/linux/images/14_81.png.jpg" alt="14_81.png.jpg" />

fun.sh 中的sum() 為自定義的函數(shù),在shell腳本中要用

function 函數(shù)名() {

command

}

這樣的格式去定義函數(shù)

上個腳本執(zhí)行過程如下:

http://wiki.jikexueyuan.com/project/linux/images/14_82.png.jpg" alt="14_82.png.jpg" />

有一點(diǎn)筆者要提醒你一下,在shell腳本中,函數(shù)一定要寫在最前面,不能出現(xiàn)在中間或者最后,因?yàn)楹瘮?shù)是要被調(diào)用的,如果還沒有出現(xiàn)就被調(diào)用,肯定是會出錯的

Shell腳本大體上就介紹這么多了,筆者所舉的例子都是最基礎(chǔ)的,所以即使你把所有例子完全掌握也不代表你的shell腳本編寫能力有多么好。所以剩下的日子里你盡量要多練習(xí),多寫腳本,你寫的腳本越多,你的能力就越強(qiáng)。希望你能夠找專門介紹shell腳本的書籍深入的去研究一下它。隨后筆者將給你留幾個shell腳本的練習(xí)題,你最好不要偷懶。

1. 編寫shell腳本,計算1-100的和;

2. 編寫shell腳本,要求輸入一個數(shù)字,然后計算出從1到輸入數(shù)字的和,要求,如果輸入的數(shù)字小于1,則重新輸入,直到輸入正確的數(shù)字為止;

3. 編寫shell腳本,把/root/目錄下的所有目錄(只需要一級)拷貝到/tmp/目錄下;

4. 編寫shell腳本,批量建立用戶user_00, user_01, … ,user_100并且所有用戶同屬于users組;

5. 編寫shell腳本,截取文件test.log中包含關(guān)鍵詞’abc’的行中的第一列(假設(shè)分隔符為”:”),然后把截取的數(shù)字排序(假設(shè)第一列為數(shù)字),然后打印出重復(fù)次數(shù)超過10次的列;

6. 編寫shell腳本,判斷輸入的IP是否正確(IP的規(guī)則是,n1.n2.n3.n4,其中1<n1<255, 0<n2<255, 0<n3<255, 0<n4<255。

以下為練習(xí)題答案:

1. #! /bin/bash

sum=0

for i in seq 1 100; do

sum=$[$i+$sum]

done

echo $sum

2. #! /bin/bash

n=0

while [ $n -lt "1" ]; do

read -p "Please input a number, it must greater than "1":" n

done

?

sum=0

for i in seq 1 $n; do

sum=$[$i+$sum]

done

echo $sum

?

3. #! /bin/bash

for f in ls /root/; do

if [ -d $f ] ; then

cp -r $f /tmp/

fi

done

?

4. #! /bin/bash

groupadd users

for i in seq 0 9; do

useradd -g users user_0$i

done

?

for j in seq 10 100; do

useradd -g users user_$j

done

?

5. #! /bin/bash

awk -F':' '$0~/abc/ ' test.log >/tmp/n.txt

sort -n n.txt |uniq -c |sort -n >/tmp/n2.txt

awk '$1>10 ' /tmp/n2.txt

?

6. #! /bin/bash

checkip() {

if echo $1 |egrep -q '^[0-9].[0-9].[0-9].[0-9]/span> ; then

a=echo $1 | awk -F. ''

b=echo $1 | awk -F. ''

c=echo $1 | awk -F. ''

d=echo $1 | awk -F. ''

?

for n in $a $b $c $d; do

if [ $n -ge 255 ] || [ $n -le 0 ]; then

echo "the number of the IP should less than 255 and greate than 0"

return 2

fi

done

else

echo "The IP you input is something wrong, the format is like 192.168.100.1"

return 1

fi

}

?

rs=1

while [ $rs -gt 0 ]; do

read -p "Please input the ip:" ip

checkip $ip

rs=echo $?

done

echo "The IP is right!"