linux之shell腳本管理(一)

在Shell腳本中執行使用if語句的好處是:能夠根據特定的條件(eg:判斷備份目錄是否存在)來決定是否執行某項操做,當知足不一樣的條件時執行 不一樣的操做(eg:備份目錄不存在則建立該目錄,不然跳過操做)。該文將分別從條件測試操做,if語句結構,應用示例這三個方面講解if語句在Shell 腳本中的應用。mysql

一、條件測試操做:sql

須要在Shell腳本中有選擇性地執行任務時,首先面臨的問題就是,如何設置命令執行的條件?編程

在Shell環境中,能夠根據命令執行後返回狀態值來判斷該命令是否成功執行,當返回值爲0是表示成功執行,不然(非0值)表示執行失敗。用於特定條件表達式的測試時,可使用Linux系統中提供的專用工具——test命令、vim

使用test測試命令時,能夠有如下兩種形式。bash

test       條件表達式工具

【 條件表達式 】測試

這兩種方式的做用徹底相同,但一般後一種形式更爲經常使用,也更貼近編程習慣。須要注意的是,方括號「[」或者「]」與條件表達式語句之間至少須要有一個空格進行分隔。spa

根據須要判斷的條件內容不一樣,條件操做也不一樣,最經常使用的條件主要包括文件狀態測試,比較整數值大小,比較字符串,以及同時判斷多個條件時的邏輯關係,下面將分別進行講解。如下主要採用方括號的測試形式。.net

1.一、測試文件狀態命令行

文件狀態測試是指根據給定的路徑名稱,判斷該名稱對應的是文件仍是目錄,或者判斷文件是否可讀,可寫,可執行等。根據判斷的狀態不一樣,在條件表達式中須要使用不一樣的操做選項。

-d:測試是否爲目錄(Directory)。

-e:測試目錄或文件是否存在(Exist)。

-f:測試是否爲文件(File)。

-r:測試當前用戶是否有權限讀取(Read)。

-w:測試當前用戶是否有權限寫入(Write)。

-x:測試當前用戶是否可執行(Excute)該文件。

-L:測試是否爲符號鏈接(Link)文件。

執行條件測試操做之後,經過預約義變量「$?」能夠得到測試命令的返回狀態值,從而可以判斷該條件是否成立(返回0值表示條件成立,非0值表示條件不成立)。但經過這種方式查看測試結果會比較繁瑣。

例1:測試「/etc/hosts」是不是文件,並經過「$?」變量查看返回狀態值,據此判斷測試結果。

1
2
3
[ -f /etc/hosts ]
echo $?
0   //返回值爲0,表示上一步測試的條件成立。

例2:測試「/media/cdrom/Server」及其父目錄是否存在,若是存在則顯示「YES」不然不輸出任何信息。

1
2
3
4
[ -e /media/cdrom/Server ] && echo "YES"
                                                                         // 無輸出表示該目錄不 存在
[ -e /media/cdrom ] && echo "YES"
YES

1.二、整數值 比較:

整數值比較是指根據給定的兩個整數值,判斷第一個數是否大於、等於、小於。。。。。。第2個數,可使用的操做選項以下:

1
2
3
4
5
6
-eq:第一個數等於(Equal)第二個數。
-ne:第一個數不等於(Not Equal)第二個數。
-gt:第一個數大於(Greater Than)第二個數。
-lt:第一個數小於(Lesser Than)第二個數。
-le:第一個數小於或等於(Lesser or Equal)第二個數。
-ge:第一個數大於或等於(Greater or Equal)第二個數。

整數值比較的測試操做在Shell腳本編寫中的應用較多,如:用於判斷磁盤使用率、登陸用戶數量是否超標以及用於控制腳本語句的循環次數等。

例1:測試當前登陸到系統中的用戶數量是否小於或等於10,是則輸出」YES「。

1
2
3
4
who | wc -l
5
[ `who | wc -l` -le 10 ] && echo 」YES"
YES

例2:提取出"/boot「分區的磁盤使用率,並判斷是否超過95%(爲了便於理解,操做步驟適當進行分解)

1
2
3
4
5
6
df -hT | grep 」/boot「 | awk '{print $6}'
12 %
BootUsage=`df -hT | grep 」/boot " | awk '{print $6}' | cut -d " %" -f 1 `
echo $BootUsage
12
[ $BootUsage -gt 95 ] && echo "YES"    //無輸出表示未超標

1.3:字符串比較:

字符串比較能夠用於檢查用戶輸入,如:在提供交互式操做時,判斷用戶輸入的選項是否與指定的變量內容相匹配。「=」、「!=」操做選項分別表示匹配、不匹配。「-z」操做選項用於檢查字符串是否爲空。其中,「!」符號用於取反,表示相反的意思。

eg:提示用戶輸入一個文件路徑,並判斷是不是「/etc/inittab」,若是是則顯示「YES」.

1
2
3
4
read -p "Location: " FilePath
Location: /etc/inittab           
[ $FilePath = "/etc/inittab" ] && echo "YES"
YES

eg: 若當前環境變量LANG的內容不是「en.US」,則輸出LANG變量的值,不然無輸出。

1
2
[ $LANG != "en.US" ] && echo $LANG
zh_CN.UTF- 8

eg: 使用touch命令創建一個新文件,測試其內容是否爲空,向文件中寫入內容後,再次進行測試。

1
2
3
4
5
6
touch zero.file
[ -z `cat zero.file` ] && echo "yes"
yes
echo "something" > zero.file
[ -z `cat zero.file` ] && echo yes
                                                    //無輸出

1.4:邏輯測試:

邏輯測試是指同時使用的兩個(或多個)條件表達式之間的關係。用戶能夠同時測試多個條件,根據這些條件是否同時成立或者只要有其中一個條件成立等狀況,來決定採起何種操做。邏輯測試可使用的操做選項以下。

>  &&:邏輯與,表示先後兩個表達式都成立時整個測試結果才爲真,不然結果爲假。在使用test命令形式進程測試時,此選項能夠改成" -a"。

>   ||:邏輯或,表示先後兩個條件至少有一個成立時整個測試結果即爲真,不然結果爲假。在使用test命令形式進行測試時,此選項能夠改成"-o「。

>  !:邏輯否,表示當指定的條件表達式不成立時,整個測試命令的結果爲真。

在上述邏輯測試的操做選項中,」&&「和」||「一般也用於間隔不一樣的命令操做,其做用是類似的。同時使用多個邏輯運算操做時,通常安裝從左到右的順序進行測試。

eg:測試當前的用戶是不是teacher,若不是則提示」Not teacher「。

1
2
3
4
echo $USER
root
[ $USER = 「teacher」 ] || echo "Not teacher"
Not teacher

eg:只要"/etc/rc.d/rc.local"或者"/etc/init.d/local'中有一個是文件,則顯示"YES",不然無任何輸出。

1
2
[ -f /etc/rc.d/rc.local ] || [ -f /etc/init.d/rc.local ] && echo "yes「
yes

eg:測試」/etc/profile「文件是否有可執行權限,若確實沒有可執行權限,則提示」No x mode.「的信息。

1
2
[ ! -x 」/etc/profile " ] && echo " No x mode."
No x mode.

eg:若當前的用戶是root且使用的Shell程序是"/bin/bash",則顯示"YES「,不然無任何輸出。

1
2
3
4
echo $USER $SHELL
root /bin/bash
[ $USER = 」root " ] && [ $SHELL = " /bin/bash " ] && echo " yes"
yes

2:if語句的結構:

前 面內容知道了一下條件測試操做,實際上使用"&&「和」||「邏輯測試能夠完成簡單的判斷並執行相應的操做,可是當須要選擇執行的命令語 句較多時,再使用這種方式將使命令行語句顯得很複雜,難以閱讀。而使用if語句,則能夠更好地體現有選擇性執行的程序結構,使得井井有條,清晰易懂。

if語句的選擇結構由易到難能夠分爲三種類型,分別適用於不一樣的應用場合。

2.一、單分支的if語句。

單分支的if語句是最簡單的選擇結構,這種結果只判斷指定的條件,當」條件成立「時執行相應的操做,不然不作任何操做。單分支使用的語句格式以下。

if 條件測試命令

then

 命令序列

fi

在上述語句中,首先經過判斷條件測試命令的返回狀態值是否爲0(條件成立),若是是,則執行then後面的一條或多臺可執行語句(命令序列),一直到fi爲止表示結束,若是條件測試命令的返回值不爲0(條件不成立),則直接去執行fi後面的語句。

2.二、雙分支的if語句。

雙分支的if語句使用了兩路命令操做,在」條件成立‘、「條件不成立時分別執行不一樣的命令序列」。雙分支使用的語句格式以下:

if 條件測試命令

then

命令序列1;

else

命令序列2;

fi

在 上述語句中,首先經過if判斷條件測試命令的返回狀態值是否爲0(條件成立),若是是,則執行then後面的一條或多條可執行語句(命令序列1),而後跳 轉至fi結束判斷,若是條件測試命令的返回狀態值不爲0(條件不成立),則執行else後面的語句,一直到fi表示結束。

2.三、多分支的if語句。

因爲if語句能夠根據條件測試命令的兩種狀態分別進行操做,因此可以嵌套使用,進行屢次判斷(如:首先判斷某學生的得分是否及格,如及格則再次判斷是否高於90分。。。)多重分支使用的語句格式以下。

if 條件測試命令1

then

命令序列1

elif 條件測試命令2

then

命令序列2

else

命令序列3

fi

上面的語法格式中只嵌套了一個elif語句,實際上if語句中能夠嵌套多個elif語句。if語句的嵌套在編寫Shell腳本時並不經常使用,由於多重嵌套容易使程序結構變得複雜。須要使用多重分支程序結構時,更多的是使用case語句來實現。

eg:檢查"/var/log/messages'文件是否存在,若存在則統計文件內容的行數並輸出,不然不作任何操做。

1
2
3
4
5
6
7
vi  chklog.sh
#!/bin/bash
LogFile= "/var/log/messages"
if [ -f $LogFile ] ; then
wc -l $LogFile
fi
sh chklog.sh                //sh是bash的符號連接

eg:提示用戶指定備份目錄的路徑,若目錄已存在則顯示提示信息後跳過,不然顯示相應提示信息後建立該目錄。

1
2
3
4
5
6
7
8
9
[root@master ~]# vi mkbak.sh
#!/bin/bash
read -p "What is your directory:" Bakdir
if [ -d $Bakdir ] ; then
echo "$Bakdir already exist."
else
echo "Bakdir is not exist,will make it."
mkdir $Bakdir
fi

eg:統計當前登陸到系統中的用戶數量,並判斷是否超過三個,如果則顯示實際數量並給出警告信息,不然列出登陸的用戶帳號成名及所在終端。

1
2
3
4
5
6
7
8
9
[root@localhost ~]# vim chkuser.sh
#!/bin/bash
UserNum=`who |wc -l`
if [ $UserNum -gt 3 ] ; then
echo "Alert , too many login users ( Total: $UserNum )."
else
  echo "Login users:"
  who | awk '{print $1,$2}'
fi

eg:檢 查portmap進程是否已經存在,若已經存在則輸出「portmap service is running」;不然檢查是否存在「/etc/rc.d/init.d/portmap」可執行腳本,存在則啓動portmap服務,不然提示「no portmap script file.」。


1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# vim chkportmap.sh
#!/bin/bash
pgrep portmap &> /dev/ null
if [ $? -eq 0 ]; then
echo "protmap service is running."
elif
[ -x "/etc/rc.d/init.d/portmap" ]; then
service portmap start
else
echo "no portmap script file."
fi

eg:每隔五分鐘監測一次mysqld服務程序的運行狀態,若發現mysqld進程已終止,則在「/var/log/messages」文件中追加寫入日誌信息(包括當時時間),並重啓mysqld服務,不然不進程任何操做。

1
2
3
4
5
6
7
8
9
10
vi chkmysql.sh
#!/bin/bash
service mysqld status &> /dev/ null
if [ $? -ne 0 ]; then
echo "At time:`date`:Mysql Server is down." >> / var /log/messages
service mysqld restart
fi
chmod u+x chkmysql.sh
crontab -e
*/ 5 * * * * /root/chkmysql.sh

三、使用for魂環語句

在Shell腳本中使用for循環語句時,能夠爲變量設置一個取值列表,每次讀取列表中不一樣的變量值並執行相關命令操做,變量值用完之後則退出循環。Shell中的for語句不須要執行條件判斷,其使用變量的取值來自於預先設置的值列表。

for語句結構:

for 變量名 in 取值列表

do

命令序列

done

在 上述語句中,使用in關鍵字爲用戶自定義變量設置了一個取值列表(以空格分隔的多個值),for語句第一次執行時首先將列表中的第一個取值賦給該變量。然 後執行do後邊的命令序列;而後再將列表中的第二個取值賦給該變量,而後執行do後邊的命令序列......如此循環,直到取值列表中的全部值都已經用 完,最後將跳至done語句,表示結束循環。

for語句示例:

eg:依次輸出三條文件信息,包括一天中的"Morning"、"Noon"、"Evening"字串。

1
2
3
4
5
6
vi showday.sh
#!/bin/bash
for TM in "Morning" "Noon" "Evening"
do
echo "The $TM of the day."
done

eg:對於使用「/bin/bash」登陸Shell的系統用戶,檢查他們在"/opt"目錄中擁有的子目錄或文件數量,若是超過100個,則列出具體數量及對應的用戶帳號。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vi chkfileown.sh
#!/bin/bash
DIR= "/opt"                //設置檢查的目標目錄
LMT= 100                //設置文件數量的限制值
ValidUsers=`grep "/bin/bash" /etc/passwd | cut -d ":" -f 1 `                //找出使用bash的系統用戶列表
for UserName in $ValidUsers
do
Num=`find $DIR -user $UserName | wc -l`              //統計每一個用戶擁有的文件數
if [ $Num -gt $LMT ] ; then
echo "$UserName have $Num files."
fi
done
sh chkfileown.sh
root have 20998 files

四、使用while循環語句

在 Shell腳本中使用while循環語句時,將能夠根據 特定的條件重複執行一個命令列表,直到該條件再也不知足時爲至。除非有特別須要,不然在腳本程序中應該是避免出現無限循環執行命令的狀況,由於若沒法跳出循 環的話,後邊的某些操做將沒法執行。爲了控制循環次數,一般會在執行的命令序列中包含修改測試條件的語句,當循環達到必定次數後,測試將再也不成立,從而可 以結束循環。

while語句的結構:

while 條件測試命令

do

命令序列

done

在 上述語句中,首先經過while判斷條件測試命令的返回狀態值是否爲0(條件成立),若是是,則執行do後邊的命令序列,而後返回到while再次進行條 件測試並判斷返回狀態值,若是條件仍然成立,則繼續執行do後邊的命令序列,而後返回到while重複條件測試......如此循環,直到所測試的條件不 成立時,跳轉到done語句,表示結束循環。

使用while循環語句時,有兩個特殊的條件測試返回值,即「true」 (真)、"false"(假)。使用「true」做爲測試條件時,條件將永遠成立,循環體內的語句將無限次執行下去,反之使用「false」則條件永遠不 成立,循環體內的語句將不會被執行,這兩個特殊值也能夠用在if語句的條件測試中。

while語句應用示例:

while語句能夠用於須要重複操做的循環系統管理任務,並可以經過設置循環條件來靈活的實現各類管理任務。

eg:由用戶從鍵盤輸入一個大於1的整數(如50),並計算從1到該數之間各整數的和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# vim sumint.sh
#!/bin/bash
read -p "Input a number (>1):" UP
i= 1
Sum= 0
while [ $i -le $UP ]
do
Sum=`expr $Sum + $i`
i=`expr $i + 1 `
done
echo "The sum of 1-$UP is : $Sum"
[root@localhost ~]# sh sumint.sh
Input a number (> 1 ): 50
The sum of 1 - 50 is : 1275


eg:批量添加20個系統用戶帳號,用戶名稱依次爲「stu1」、"stu2"、「stu3」、.......「stu20」,各用戶的初始密碼均設置爲「123456」。


1
2
3
4
5
6
7
8
9
[root@localhost ~]# vim add20users.sh
#!/bin/bash
i= 1
while [ $i -le 20 ]
do
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/ null
i=`expr $i + 1 `
done

sh add20users.sh

eg:編寫一個批量刪除用戶的腳本程序,將上面添加的20個用戶刪除。

1
2
3
4
5
6
7
8
[root@localhost ~]# vim del20users.sh
#!/bin/bash
i= 1
while [ $i -le 20 ]
do
userdel -r stu$i
i=`expr $i + 1 `
done

再次查看: cat /etc/passwd 就會發現那些用戶再也不存在。

說了if、for 、while、語句後,就能夠編寫通常的系統管理任務腳本了,記得多多練習!其實除了這些Shell腳本語句外,還有好多好多,如:

case分支語句,until循環、shift移位,以及break和continue循環中斷語句。你們能夠查詢!後續有時間我也會推出~

相關文章
相關標籤/搜索