腳本編程中的面向過程:順序執行,選擇執行,循環執行。在談shell腳本以前咱們來認識幾個bash的特殊變量,並瞭解一下bash腳本的測試。
shell
1、shell腳本中的特殊變量express
$0 獲取當前執行的shell腳本的文件名編程
$n 獲取當前執行的shell腳本的第n個參數值,n=1..9bash
$* 獲取當前shell的全部參數 「$1 $2 $3 …ide
$# 獲取當前shell命令行中參數的總個數oop
$$ 獲取當前shell的進程號(PID)測試
$! 執行上一個指令的PIDui
$? 獲取執行的上一個指令的返回值(0 爲成功, 非零爲失敗)spa
$@ 這個程序的全部參數 「$1″ 「$2″ 「$3″ 「…」命令行
2、shell腳本中的測試
一、條件測試
[expression] 命令行直接執行
[[ expression ]] 關鍵字的變量引用 判斷執行
注:bash命令有執行狀態返回值,而命令的執行結果與命令狀態返回值大相徑庭的兩個概念。其區別是命令執行後產生的結果,是否執行成功就有執行狀態返回值判斷 :echo$?返回值是0 執行成功,1-255 執行失敗。
二、整數測試
expression :數值1 比較符號 數值2
-gt :大於 $A -gt $B --> A>B
-ge : 大於或等於 $A -ge $B --> A>=B
-eq : 等於 $A -eq $B --> A=B
-lt : 小於 $A -lt $B --> A<B
-le : 小於或等於 $A -le $B --> A<=B
-ne : 不等於 $A -ne $B --> A!=B
三、字符測試
expression :字符1 比較符號 字符2
> : 大於 < : 小於
== : 等於
=~ :判斷左邊的字符是否可以被右邊的字符模式匹配
注:字符匹配命令 [[ $opt1 =~ $opt2 ]],通常作行首行尾錨定,$opt2不要加引號。
字符單目操做 :-z $STRING : 爲空則爲真,不空則爲假
-n $STRING :爲空則爲假,不空則爲真
四、組合測試
&&:與 ||:或 !:非
短路操做
與運算:1 && 1 =1 ,0 && {0,1} =0 ,1 && 0 =0
或運算:1 || {0 ,1} =1 , 0 || 1 =1 , 0 || 0 =0
五、文件測試
操做符 文件路徑
-f:測試其是否爲普通文件,即ls -l時文件類型爲-的文件
-d: 測試其是否爲目錄文件,即ls -l時文件類型爲d的文件
-e: 測試文件是否存在,存在爲真,不然爲假
-r: 測試文件對當前用戶來講是否可讀
-w: 測試文件對當前用戶來講是否可寫
-x: 測試文件對當前用戶來講是否可執行
-s: 測試文件大小是否不空,不空則真,空則假
3、for循環結構
語法結構:
for 變量 in 列表 ;do
語句1 ;語句2 ;···
done
注:循環必須有退出條件,否則會成爲死循環,此處列表即爲限定條件。
4、while循環結構
語法結構:
while 測試條件 ;do
語句1;語句2;···
done
5、until循環結構
語法結構:
until 測試條件 ;do
語句1;語句2;···
done
六,for, while, until 三者的對比
三者如何退出循環:
for循環語句是遍歷列表中的元素完成;
while循環語句是在循環體改變測試條件時,條件知足就循環,直到條件再也不知足則退出循環;
until循環語句是在循環體改變測試條件時,條件不知足就循環,直到條件知足時則退出循環。
實戰演練
一、寫一個腳本
使用for循環統計/etc/fstab、/etc/rc.d/rc.sysinit、/etc/inittab文件中各自以#開頭的行的行數和空白行數;
#!/bin/bash for File in /etc/fstab /etc/rc.d/rc.sysinit /etc/inittab; do echo "$File:" echo -e "\t#lines: `grep "^#" $File | wc -l`" echo -e "\tspace lines: `grep "^$" $File | wc -l`" done
二、寫一個腳本
使用for循環,分別將user一、user2和user3加入到testgrp組中,以其爲額外組;
#!/bin/bash groupadd testgrp for User in user1 user2 user3; do usermod -a -G testgrp $User done
三、寫一個腳本
使用for循環,複製/etc/fstab、/etc/inittab和/etc/rc.d/init.d/functions文件至/tmp/目錄中,並重命名爲原有的名稱以後加當前日期,如第一個文件爲/tmp/fstab-2013-07-
#!/bin/bash for File in /etc/fstab /etc/inittab /etc/rc.d/init.d/functions; do Filename= basename $File cp $File /tmp/$Filename-`date +%F` done
四、寫一個腳本
求200之內全部爲3的整數倍的整數之和;
#!/bin/bash # Sum=0 for I in {1..200}; do if [ $[$I%3] -eq 0 ]; then Sum=$[$Sum+$I] fi done echo "Sum: $Sum."
五、寫一個腳本
計算
100
之內全部奇數的和以及全部偶數的和;分別顯示之;
#
五、寫一個腳本
若是用戶的ID號爲偶數,則顯示其名稱和shell;對全部用戶執行此操做;
#!/bin/bash while read LINE; do Uid=`echo $LINE | cut -d: -f3` if [ $[$Uid%2] -eq 0 ]; then echo $LINE | cut -d: -f1,7 fi done < /etc/passwd
六、寫一個腳本
每隔5秒查看hadoop用戶是否登陸,若是登陸,顯示其登陸並退出;不然,顯示當前時間,並說明hadoop還沒有登陸:
#!/bin/bash who | grep "^hadoop" &> /dev/null RetVal=$? until [ $RetVal -eq 0 ]; do date sleep 5 who | grep "^hadoop" &> /dev/null RetVal=$? done echo "hadoop is here."
七、寫一個腳本
使用for,while,until三個循環語句,計算100之內全部正整數的和;
fo語句
#!/bin/bash # Sum=0 for I in {1..100}; do let Sum=$[$Sum+$I] done echo $Sum
while語句
#!/bin/bash Sum=0 Count=1 while [ $Count -lt 100 ]; do let Sum+=$Count let Count++ done echo $Sum
until語句
#!/bin/bash Sum=0 Count=1 until [ $Count -gt 100 ]; do let Sum+=$Count let Count++ done echo $Sum
八、寫一個腳本
使用while和until分別實現「轉換用戶輸入的字符爲大寫,除了quit(碰見quit退出);」
while語句
#!/bin/bash read -p "A string: " String while [ "$String" != 'quit' ]; do echo $String | tr 'a-z' 'A-Z' read -p "Next [quit for quiting]: " String done
until語句
read -p "A string: " String until [ "$String" == 'quit' ]; do echo $String | tr 'a-z' 'A-Z' read -p "Next [quit for quiting]: " String done
九、寫一個腳本
計算100之內全部偶數的和以及奇數的和;在一個循環中實現;
要求:分別使用for,while,until各自獨立實現。
for語句
#!/bin/bash EvenSum=0 OddSum=0 for I in {1..100}; do if [ $[$I%2] -eq 0 ]; then EvenSum=$[$EvenSum+$I] else OddSum=$[$OddSum+$I] fi done echo "EvenSum is: $EvenSum. OddSum is: $OddSum."
while語句
#!/bin/bash EvenSum=0 OddSum=0 Count=0 while [ $Count -le 100 ]; do if [ $[$Count%2] -eq 0 ]; then let Sum+=$Count let count++ echo "EvenSum is:$Sum" else let Sum+=$Count echo "OddSum is:$Sum" fi done
until語句
#!/bin/bash EvenSum=0 OddSum=0 Count=0 until [ $Count -gt 100 ]; do if [ $[$Count%2] -eq 0 ]; then let Sum+=$Count let count++ echo "EvenSum is:$Sum" else let Sum+=$Count echo "OddSum is:$Sum" fi done