BASH編寫入門與例項
阿新 • • 發佈:2020-10-20
怎麼寫shell指令碼: 。使用任何編輯工具編寫shell指令碼 例如vi -#!/bin/bash #在第一行放置頭格式說明
-#!/usr/bin/gawk //awk需要新增的頭格式,讓系統知道用什麼方式去解析此檔案
-#!/usr/local/bin/python //python的頭格式
。在寫完shell指令碼之後,設定指令碼執行許可權 -chmod +x you-script-name -chmod 755 your-script-name 。執行你的指令碼做測試 -bash your-script-name -sh your-script-name -./your-script-name
shell中的變數
。Linux(shell)中有兩種型別的變數:
-系統變數:由Linux系統本身維護,通常為大寫的變數名
-使用者定義變數(UDV):由使用者建立和維護,通常小寫
。檢視系統變數可以通過Linux指令set羅列出來,也可以輸入declare
。在呼叫變數時,在名稱前加以“$"(美元符號)
-echo $USERNAME
-echo $HOME
如何定義使用者自己的變數 。要定義UDV可以使用下面的語法: 變數名=值 (注意:等號之間沒有空格) 。通過”=“將右邊的值賦給左邊的變數 no=10 #正確 10=no #錯誤,值必須在右邊 vech=Bus #頂一個一個vech的變數值為Bus n= 30 #錯誤,等號右邊存在空格 n =20 #錯誤,等號左邊存在空格
。只讀變數設定:
#readonly BOOK=”Linux“
#BOOK=”Windows“ //將會報錯。
取消變數#unset BOOK
彩色Shell輸出
。echo -e 指令可以在控制檯輸出彩色的字元。
。色彩分為前景色和背景色,十位數的數字3或4表示
-前景色30-37(以3x代表)
-背景色40-47(以4x代表)
。個位數表示為色彩
30(黑色)、31(紅色)、32(綠色)、33(黃色)、34(藍色)、35(洋紅)、36(青色)、37(白色)。
。前景色和背景色個位數不要一致,否則看不到任何資訊(可以用在密碼輸入處)
彩色Shell輸出二 。使用格式: - \033[前景色;背景色m #同事更改前/背景色 - \033[前景色m #只更改前景色 - \033[背景色m #只更改背景色 - \033[0m #還原所有的前/背景色,最後部分一定要還原色彩 。echo "You are login to \033[34;40m bulefox \033[0m system" //這裡的第一個\033[[34;40m是說前景色和背景色設定,而\033則是讓所有的前景色和背景色還原。-列印藍色的bulefox 。下面的程式碼用在防止密碼被窺探 echo "Please input a password”
echo -e “\033[34;44m" read PASSWD;
echo -e "\033[0m" echo PASSWD | openssl md5
echo命令
。使用echo 命令可以顯示文字或比變數的值
。echo 【選項】【字元,變數...】
。選項
-n 不換行輸出,預設echo一次換一行,用在持續的列印輸出
-e啟用轉義字元解析
\a 響鈴 \b 退格 \c去除尾部的新行
\n 新的一行 \r 回車 \t 水平製表符功能
\\ 斜槓
echo -e "An apple a day keeps away \a\t\tdoctor\n"
shell中數學計算 。使用下面的語法執行數學運算,注意中間都存在空格,一次只能處理兩個數字 語法:expr 運算元1 數學計算 運算元2 expr 1+3 #加法計算 expr 10/2 除法計算 expr 20%3 求餘數 expr 10\*3 #乘法他叔,由於”*“星號為萬用字元之一,必須對*轉義 echo ‘expr 6+3‘ #顯示結果,注意”‘"(斜點)的使用,代表先行執行Bash命令 。如果使用echo “expr 6+3”或者echo 'expr 6+3'將顯示“expr 6+3”字元本身
將表示式計算結果賦值給變數方法:
#TMP=$(expr 3333 \*10) //將3333*10的結果賦值給變數TMP
#echo “$((1+100/3*6))" // 可以使用括號的方式進行運算,這種限制比較少
引號的使用
。我們來區分一下引號
”“(雙引號) 對”\"做轉義,對“$"的變數做解析
''(單引號) 其中的內容不作任何修改
‘‘(斜點) 用來執行命令
。請觀察下面的命令區別:
-echo ”Today is date“ #輸出Today is date
-echo ”Today is ‘date‘“ #輸出Today is 及日期
-echo 'Today is ‘date‘’ #原樣輸出Today is ‘date‘
退出和退出狀態 。在Linux執行指令,它將返回兩種型別的值,用來判斷此前執行的命令或shell指令碼成功與否 -返回0,命令執行成功 -返回任何不為0,命令不成功或者執行中有一些錯誤 。這些值稱呼為退出狀態,可以通過$?檢查退出狀態 -rm nonexist-file -echo $? -ls -echo $? //判斷前面一條指令執行成功與否,立刻執行echo $?檢視返回值,0表示執行成功,否則執行失敗。
萬用字元的使用 。”*“星號代表任何的字元出現0到多次 ls /lib/*.so //任何以.so為字尾的檔案 ls /lib/lib*.so.* //以lib開頭+.so.+任何其他字尾 。”?“問號代表一個而且只有一個任何字元 ls /lib/lib??.so.? //此檔名長度為10 。”[]“括號內提供的字元選擇一個 ls /lib/lib[bcp]*.so //b,c,p選一,libb,libc,libp 。”[-]“括號內一段字元,0-9數字,a-z小寫,A-Z大寫 ls /lib/lib[b-p]*.so //從b到p選擇一個
ls /lib/lib[a-z]*.so等同於ls /lib/lib[ab-z]*.so 。”[^]"括號內的都排除掉,[^bc]除了b和c以外的其他全部 ls /lib/lib[^c]*.so.*
命令列的處理
。Linux絕大多數命令可以帶引數和選項,請識別下面的命令帶有多少引數
#命令 #引數總數($#)
ls foo #1
cp y y.bak #2
date #0
tail -10 myf #2
mail raj #1
sort -r -r myf #2
命令列引數 。根據前面觀察的結果 -$#儲存著命令後面所帶的引數的總數 -$*或者$@將命令後的所有引數作為一個字串儲存
-$0 永遠是命令本身
-$1,2,3... 命令引數
shell指令碼中條件判斷
。返回shell中0(代表True)或1(False)結果
-if/then結構
-test或者[...]執行shell測試,返回shell結果
。Bash2.02版本以上[[...]]
。返回常規程式語言格式的結果
-((...))和let...還可以做數字的比較
。bc指令提供我們對條件的測試
測試條件:
。字元比較 數字比較 代表意思
== -eq 相等
> -gt 大於
< -lt 小於
!= -ne 不等於
<=/>= -le/ge 小於等於/大於等於
多個條件測試時
-a並且,邏輯與-o或者,邏輯或
test命令或[] 。[]中寫入測試條件,注意條件和開/閉中括號之間要保留空格 。初學者使用此模式時,要特別注意,0代表TRUE,可以理解成沒有錯誤,而1代表FALSE if [ 0 ];then echo "0 is true" else echo "0 is false" fi
if...else...fi
。語法:
if [ 條件判斷]
then
命令1 #上面條件判斷結果為0,代表TRUE
命令2
else
命令3 #上面條件判斷結果為1,代表FALSE
命令4
fi
if語句直接使用示例
。if語句可以直接使用Shell指令,再根據$?結果判斷
DIR=/var/test
if cd $DIR &> /dev/null;then #直接丟棄錯誤訊息,這裡由於不需要判斷條件,這裡的條件就可以去掉[]
echo "now in $DIR"
else
echo "Can't change to $DIR"
fi
測試檔案/資料夾屬性 。常見判斷 -a #檔案是否存在 -b #檔案是否為塊裝置 -d #檔案是否為目錄 -s #檔案大小是否為0 -r #檔案是否具有可讀許可權 -w #檔案是否具有可寫許可權 -x #檔案是否具有可執行許可權 。man bash可以得到更為詳盡的幫助
#[ -f /etc/passwd ]; echo $? //檢視/etc/passwd檔案是否存在
if語句巢狀
。一步一步測試時,可能需要if-then-else語句的巢狀使用
OSCH=0
echo “1.Unix(IBM AIX)”
echo “2.Linux(Red Hat Enterprise Linux)”
read OSCH
if [ $OSCH -eq 1 ]; then
echo "You pick UNIX OS"
else
if [ $OSCH -eq 2 ];then
echo "Your Pick Linux OS"
else
echo "What you don't Like Linux/Unix OS"
fi
fi
多級if-then-else
。多級if-then-else可以替換掉if-then-else的巢狀使用,直接使用另一個/多個條件測試,請將之前的程式修改以下語法
。語法
if [ 測試條件1 ];then
命令1
elif [ 測試條件2 ];then
命令2
elif [ 測試條件n ];then
命令n
else
命令
fi
退出和退出狀態
。在Linux執行指令,它將返回兩種型別的值,用來判斷此前執行的命令或shell指令碼成功與否
-返回0,命令成功
-返回任何不為0,命令不成功或者在執行中有一些錯誤
。這些值稱呼為退出狀態,可以通過$?檢查退出狀態
-rm nonexit-file
-echo $?
-ls
-echo $?
case語句 。case語句是多級if-then-elif語句的替代語句。可以讓你多個值做匹配測試,更方便讀寫。 。語法: case 變數名 in 匹配1) 命令1;; 匹配2) 命令2;; 匹配N) 命令N;; *) 命令;; esac
比較以下兩段程式碼:、
將手動寫的指令碼加入到chkconfig裡面步驟:
比如已經編寫好的myserv.sh指令碼,需要加入到開機啟動裡面
1.將此指令碼加入到/etc/init.d
#mv myserv.sh /etc/init.d/myserv
2.需要在指令碼中新增chkconfig和descirption資訊,可以參考/etc/init.d/network部分,下圖中標色部分即為需要新增內容
3.chkconfig --add myserv //新增此服務到chkcofnig下
4.chkcofnig --list myserv //檢視該服務在不同級別下啟停狀態。
Shell中loop迴圈 迴圈的定義: -計算機可以重複一而再,再而三的執行特定的指令,直到給定的條件滿足為止,重複執行的這一組指令就叫做loop 。Bash中支援 -for loop -while loop 。注意每個迴圈使用時 首先,用在迴圈中的變數必須要在迴圈前初始化 對每次迴圈都需要對條件做測試 在迴圈體中執行一次需要對迴圈測試條件值修改
for loop
。語法:
for 變數名 in 列表
do
迴圈體
done
。列表就是一個集合,集合由空格間隔,可以使以下的集中:
-數字/字元集合
-1 2 5 7 9
-{1...254}
-檔案集合
-/etc/*.conf
-指令結果集合
-$(find /etc/ -perm -003)
例項1(數字迴圈): 建立file1,2,3,4檔案 #touch file{1,2,3,4,5} #vim test.sh 內容如下: #!/bin/bash for FILENAME in file1 file2 file3 file5 do echo "You are going to remove the $FILENAME rm $FILENAME -f done 例項2: 。數字集合 #vim test.sh 內容如下: #!/bin/bash echo "#!/bin/bash" > /bin/setFilewall.sh for IP in {1...254} do echo "iptables -I INPUT -s 192.168.0.$IP -p tcp -m state --state NEW -j ACCEPT" >> /bin/setFirewall.sh done
/etc/sysconfig/selinx //其中/etc/sysconfig通過dirname可以獲取,而selinux則可以通過basename獲取。
#date +%F //可以獲取當前日期
for loop例項三
for FILE in $(find /var/ -size +10M)
do
rm -f $FILE
logger "$FILE has been deleted"
echo -e "\033[33m$FILE\033[0mhas been deleted">>/var/tmp/largefile.log
done
獲取某個檔案中的空格或者換行的ip地址方法: #cat /etc/testservers.conf | grep -Ev '^(#|$)' 如獲取以下檔案中的有效ip #vim testservers.conf 檔案內容如下: #This file is the host ip #172.23.2.1 192.168.1.1 #FTP Server 192.13.1.1 127.0.0.1 192.156.1.1
全文搜尋例項:
此指令碼用於搜多某個目錄下所有檔案裡面是否含有某個關鍵字
指令碼內容如下:
#!/bin/bash DIR=$1 KEYWORD=$2 for FILENAME in $(find $DIE -type f) do if grep $KEYWORD $FILENAME &> /dev/null;then echo "The file -->$FILENAME has the keyword" #else fi done
for loop迴圈巢狀一
for NUM1 in {1. .9}
do
for NUM2 in {1..9}
do
RES = $((NUM1*NUM2)) #注意此處沒有呼叫$
echo "$NUM1*$NUM2=$RES"
done
done
#請把此程式碼改成C語言格式
while迴圈
。語法:
-while [條件測試]
do
命令
done
。注意要修改測試條件的值,防止死迴圈。還可以與if-then-fi巢狀使用,使用exit函式退出
read $1 $2 $3 //可以用來讀取文字檔案中某一行的第一個,第二個,第三個不規則的引數作為輸入
函式的使用
。函式是一系列的指令和命令
。本身不執行,可以多次呼叫,可以簡化程式碼
。語法
函式()
{
命令1;命令2
return #返回值
}
函式的引數
。函式也可以作為一個程式一樣執行,接收引數
-fname $arg1 $arg2
-這和shell中位置引數一樣,我們可以對$1,$2測試
max()
{
if (($1>$2));then
return $1 #注意,此時函式已經結束了
fi
return $2
}
max 10 100
echo $? #通過$?取得函式的返回值
函式示例 setPath() { PATH=/bin:/usr/bin if (($UID == 0 ));then #如果為root PATH=$PATH:/usr/bin/sbin:/sbin #路徑追加sbin的目錄 fi if (($2 == "after"));then #根據位置引數2,決定如何新增新路徑 PATH=$PATH:$1 #在原PATH後面追加 else PATH=$1:$PATH #在原PATH之前新增 fi }
getopts命令
。getopts用來檢測命令中傳遞給指令碼的有效引數
。通常用在while loop中
。語法:
-getopts <選項字串> <變數1>
。<選項字串>包含了要識別的選項字元;如果字元前存在"-"(橫槓),而此選項期待著有一個引數,他們之間用空格空開。
。每次呼叫getopts的時候,他講下一選項設定給<變數1>
。當選項需要引數時,getopts將引數設定給變數OPTARG
。如果選項不正確,返回 ? 給<變數1>
getopts示例 while getopts n:a: opt #此程式就有-n和-a選項,注意選項字串尾部的冒號(:) do case "$opt" in n) name="$OPTARG";; a) age="$OPTARG";; \?) echo “Usage:..." esac done echo ”Welcome $name,you age is $age"