shell腳本的三種元素

● 第一行的腳本聲明(#!):指定解釋此腳本文件的 Shell 程序;
● 第二行的注釋信息(#):對(duì)腳本功能和某些命令的介紹信息;
● 第三行的可執(zhí)行語句:執(zhí)行的Linux命令。

[root@kylin ~]# vim hello.sh#!/bin/bash#Example of printing "hello world!"echo "Hello World!"

運(yùn)行腳本的兩種方法

● 作為可執(zhí)行程序

[root@kylin ~]# chmod +x ./hello.sh  #使腳本具有執(zhí)行權(quán)限[root@kylin ~]# ./hello.sh  #執(zhí)行腳本

● 作為解釋器參數(shù)

[root@kylin ~]# /bin/bash hello.sh[root@kylin ~]# /bin/sh hello.sh

變量

使用變量

● 變量外的花括號(hào)加不加都能正常引用變量,但推薦所有變量都加上{},幫助解釋器識(shí)別變量的邊界,養(yǎng)成好的編程習(xí)慣。

[root@kylin ~]# vim company.sh#!/bin/bash#Examples of using variablescompany="kylin"echo $companyecho ${company} 

刪除變量

● 使用unset刪除變量,變量刪除后不能再次使用。以下實(shí)例執(zhí)行后無輸出:

[root@kylin ~]# vim unset.sh#!/bin/bash#Example of deleting variablesmyUrl="https://www.kylinos.cn"unset myUrlecho $myUrl

傳遞參數(shù)

● shell腳本內(nèi)設(shè)了接受參數(shù)的變量,傳遞參數(shù)時(shí)使用空格間隔。常用傳參變量如下表:
變量含義
$0當(dāng)前Shell腳本程序的名稱
$#總共有幾個(gè)參數(shù)
$*所有位置的參數(shù)值
$?顯示上一次命令的執(zhí)行返回值
$1、$2、$3分別對(duì)應(yīng)著第N個(gè)位置的參數(shù)值

● 以下實(shí)例在運(yùn)行腳本時(shí),向腳本傳遞5個(gè)參數(shù),在腳本中調(diào)用參數(shù):

[root@kylin ~]# vim para.sh#!/bin/bash#Example of passing parametersecho "當(dāng)前腳本名稱為$0"echo "總共有$#個(gè)參數(shù),分別是$*。"echo "第1個(gè)參數(shù)為$1,第5個(gè)為$5。"[root@kylin ~]# bash para.sh one two three four five six

給腳本添加執(zhí)行權(quán)限,執(zhí)行結(jié)果如下:

[root@kylin ~]# chmod +x para.sh[root@kylin ~]# ./para.sh

當(dāng)前腳本名稱為para.sh
總共有6個(gè)參數(shù),分別是one two three four five six
第1個(gè)參數(shù)為one,第5個(gè)為five

運(yùn)算符

文件測(cè)試運(yùn)算符

判斷文件是否存在或權(quán)限是否滿足等,常用的參數(shù)列表如下:
操作符說明
-d測(cè)試文件是否為目錄類型,如果是,則返回true
-e檢查文件(包括目錄)是否存在,如果是,則返回true
-f測(cè)試是否為一般文件(既不是目錄,也不是設(shè)備文件),如果是,則返回true
-r測(cè)試當(dāng)前用戶是否有權(quán)限讀取,如果有,則返回true
-w測(cè)試當(dāng)前用戶是否有權(quán)限寫入,如果有,則返回true
-x測(cè)試當(dāng)前用戶是否有權(quán)限執(zhí)行,如果有,則返回true

● 實(shí)例:判斷/etc/fstab是否為目錄類型的文件:返回值為非零值,代表它不是目錄,或這個(gè)目錄不存在

[root@kylin ~]# vim file.sh#!/bin/bashfile="/etc/fstab"if [ -d $file ]then   echo "文件$file是一個(gè)目錄"else   echo "文件$file不是一個(gè)目錄或不存在"fi

執(zhí)行腳本,輸出結(jié)果如下:
文件/etc/fstab不是一個(gè)目錄或不存在

邏輯運(yùn)算符

運(yùn)算符含義
&&邏輯"與" && 前面的命令執(zhí)行成功后才會(huì)執(zhí)行它后面的命令
||邏輯"或" || 前面的命令執(zhí)行失敗后才會(huì)執(zhí)行它后面的命令
!邏輯"非" 把條件測(cè)試中的判斷結(jié)果取相反值,之前是正確則變錯(cuò)誤,錯(cuò)誤則變正確

● 實(shí)例1:判斷/dev/cdrom文件是否存在,若存在則輸出Exist字樣

[root@kylin ~]# [ -e /dev/cdrom ] && echo "Exist"Exist

● 實(shí)例2:使用環(huán)境變量USER,判斷當(dāng)前用戶是否為非管理員身份

[root@kylin ~]# echo $USERroot[root@kylin ~]# [ $USER = root ] || echo "user"[root@kylin ~]# su - test [test@kylin ~]$ [ $USER = root ] || echo "user"user

● 實(shí)例3:判斷當(dāng)前登錄的用戶是否為非管理員用戶,若條件成立則輸出user字樣,條件不滿足則輸出root字樣

[root@kylin ~]# [ ! $USER = root ] && echo "user" || echo "root"root
整數(shù)比較運(yùn)算符(關(guān)系運(yùn)算符)
只支持對(duì)數(shù)字的操作,不能將數(shù)字與字符串、文件等內(nèi)容一起操作。可用的整數(shù)比較運(yùn)算符如表所示:
操作符作用
-eq是否等于
-ne是否不等于
-gt是否大于
-lt是否小于
-le是否等于或小于
-ge是否大于或等于

● 實(shí)例1:判斷當(dāng)前剩余內(nèi)存大小是否小于1024,若小于則提示"Insufficient Memory",否則提示"Sufficient Memory"(使用free -m命令查看內(nèi)存使用量情況(單位為MB),通過grep Mem:命令過濾出剩余內(nèi)存量的行,再用awk {print $4}命令只保留第四列,即可得到剩余內(nèi)存大?。?/p>

[root@kylin ~]# vim mem.sh#!/bin/bashFreeMem=`free -m | grep Mem: | awk {print $4}`[ $FreeMem -lt 1024 ] && echo "Insufficient Memory" || echo "Sufficient Memory"[root@kylin ~]# [root@kylin ~]# chmod +x mem.sh[root@kylin ~]# ./mem.shSufficient Memory

字符串運(yùn)算符

判斷字符串是否為空值,或兩個(gè)字符串是否相同,可用來判斷某個(gè)變量是否被定義(即內(nèi)容為空值)。字符串比較中常見的運(yùn)算符如表所示:
操作符作用
=比較字符串內(nèi)容是否相同
!=比較字符串內(nèi)容是否不同
-z判斷字符串內(nèi)容是否為空

● 實(shí)例1:通過判斷String變量是否為空值,進(jìn)而判斷是否定義了該變量,返回值為0,則未定義該變量

[root@kylin ~]# [ -z $String ][root@kylin ~]# echo $?0

● 實(shí)例2:判斷當(dāng)前語言環(huán)境變量值LANG是否為非英文(en.US),若是,則輸出"Not en.US"字樣

[root@kylin ~]# echo $LANG[root@kylin ~]# [ ! $LANG = "en.US" ] && echo "Not en.US"

流程控制

if條件測(cè)試語句

單分支結(jié)構(gòu):if then fi

● 實(shí)例1:適用于終端命令提示符的寫法,如果10等于10,那么輸出"true"

[root@kylin ~]# if [ 10 -eq 10 ]; then echo "true"; fitrue

● 實(shí)例2:判斷/media/cdrom目錄是否存在,若不存在就創(chuàng)建這個(gè)目錄,反之則結(jié)束條件判斷和整個(gè)Shell腳本

[root@kylin ~]# vim mkcdrom.sh#!/bin/bashDIR="/media/cdrom"if [ ! -d $DIR ]then            mkdir -p $DIRfi 

驗(yàn)證/media/cdrom目錄是否已經(jīng)成功創(chuàng)建:

[root@kylin ~]# bash mkcdrom.sh[root@kylin ~]# ls -ld /media/cdromdrwxr-xr-x. 2 root root 6 Oct 13 21:34 /media/cdrom

雙分支結(jié)構(gòu):if then else fi

● 實(shí)例1:驗(yàn)證某臺(tái)主機(jī)是否在線。返回值若為0,顯示主機(jī)在線信息,否則顯示主機(jī)不在線信息。(使用ping命令來測(cè)試與對(duì)方主機(jī)的網(wǎng)絡(luò)聯(lián)通性,-c參數(shù)來規(guī)定嘗試的次數(shù),-i參數(shù)定義每個(gè)數(shù)據(jù)包的發(fā)送間隔,-W參數(shù)定義等待超時(shí)時(shí)間。)

[root@kylin ~]# vim chkhost.sh#!/bin/bashping -c 3 -i 0.2 -W 3 $1 &> /dev/nullif [ $? -eq 0 ]then        echo "Host $1 is On-line."else        echo "Host $1 is Off-line."fi

驗(yàn)證腳本的效果:

[root@kylin ~]# bash chkhost.sh 10.1.160.183Host 10.1.160.183 is On-line.[root@kylin ~]# bash chkhost.sh 10.1.160.184Host 10.1.160.184 is Off-line.

多分支結(jié)構(gòu):if then elif then else fi

● 實(shí)例1:判斷用戶輸入的分?jǐn)?shù)在哪個(gè)成績(jī)區(qū)間內(nèi),輸出Excellent、Pass、Fail等提示信息。(read用來讀取用戶輸入的信息,把接收到的用戶輸入信息賦值給后面的指定變量,-p參數(shù)給予用戶一些提示信息。)
用戶輸入的分?jǐn)?shù)(GRADE)輸出信息
85≤GRADE≤100Excellent
70≤GRADE≤84Pass
othersFail
[root@kylin ~]# vim chkscore.sh#!/bin/bashread -p "Enter your score(0-100):" GRADEif [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then        echo "$GRADE is Excellent"elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then        echo "$GRADE is Pass"else        echo "$GRADE is Fail" fi[root@linuxprobe ~]# bash chkscore.shEnter your score(0-100):8888 is Excellent[root@linuxprobe ~]# bash chkscore.sh Enter your score(0-100):8080 is Pass

for條件循環(huán)語句

● 實(shí)例1:批量創(chuàng)建用戶
創(chuàng)建用戶名列表文件,一行一個(gè)用戶名:

[root@kylin ~]# vim users.txttest1test2test3test4test5test6

使用read命令讀取用戶輸入的密碼值,賦值給PASSWD變量,通過-p參數(shù)向用戶顯示一段提示信息,告訴用戶正在輸入的內(nèi)容即將作為賬戶密碼。在執(zhí)行該腳本后,會(huì)自動(dòng)使用從列表文件users.txt中獲取到所有的用戶名稱,然后逐一使用“id 用戶名”命令查看用戶的信息,并使用$?判斷這條命令是否執(zhí)行成功,也就是判斷該用戶是否已經(jīng)存在。

[root@kylin ~]# vim addusers.sh#!/bin/bashread -p "Enter The Users Password : " PASSWDfor UNAME in `cat users.txt`do        id $UNAME &> /dev/null        if [ $? -eq 0 ]        then                echo "$UNAME , Already exists"        else                useradd $UNAME &> /dev/null                echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null                echo "$UNAME , Create success"        fidone

運(yùn)行腳本,并檢查是否創(chuàng)建成功

[root@kylin ~]# bash addusers.shEnter The Users Password : linuxprobetest1 , Create successtest2 , Create successtest3 , Create successtest4 , Create successtest5 , Create successtest6 , Create success[root@kylin ~]# tail -6 /etc/passwd

while條件循環(huán)語句

● 實(shí)例1:猜測(cè)數(shù)值大小
使用$RANDOM變量調(diào)取一個(gè)隨機(jī)數(shù)(范圍為0~32767),將這個(gè)隨機(jī)數(shù)對(duì)1000進(jìn)行取余操作,并使用expr命令取得其結(jié)果,再用這個(gè)數(shù)值與用戶通過read命令輸入的數(shù)值進(jìn)行比較判斷。

判斷語句分為三種情況,分別是判斷用戶輸入的數(shù)值是等于、大于還是小于使用expr命令取得的數(shù)值。

while條件循環(huán)語句中的條件測(cè)試始終為true,因此判斷語句會(huì)無限執(zhí)行下去,直到用戶輸入的數(shù)值等于expr命令取得的數(shù)值后,運(yùn)行exit 0命令,終止腳本的執(zhí)行。

[root@kylin ~]# vim Guess.sh#!/bin/bashPRICE=$(expr $RANDOM % 1000)TIMES=0echo "商品實(shí)際價(jià)格為0-999之間,猜猜看是多少?"while truedo        read -p "請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:" INT        let TIMES++        if [ $INT -eq $PRICE ] ; then                echo "恭喜您答對(duì)了,實(shí)際價(jià)格是 $PRICE"                echo "您總共猜測(cè)了 $TIMES 次"                exit        elif [ $INT -gt $PRICE ] ; then                echo "太高了!"        else                echo "太低了!"        fidone

運(yùn)行腳本:

[root@kylin ~]# bash Guess.sh商品實(shí)際價(jià)格為0-999之間,猜猜看是多少?請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:500太低了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:800太高了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:650太低了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:720太高了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:690太低了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:700太高了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:695太高了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:692太高了!請(qǐng)輸入您猜測(cè)的價(jià)格數(shù)目:691恭喜您答對(duì)了,實(shí)際價(jià)格是 691您總共猜測(cè)了 9 次

case條件測(cè)試語句

case語句在多個(gè)范圍內(nèi)匹配數(shù)據(jù),若匹配成功則執(zhí)行相關(guān)命令并結(jié)束整個(gè)條件測(cè)試;如果數(shù)據(jù)不在所列出的范圍內(nèi),則去執(zhí)行星號(hào)(*)中所定義的默認(rèn)命令。

● 實(shí)例1:判斷用戶輸入內(nèi)容的類型
提示用戶輸入一個(gè)字符并將其賦值給變量KEY,根據(jù)變量KEY的值向用戶顯示其值是字母、數(shù)字還是其他字符。

[root@kylin ~]# vim Checkkeys.sh#!/bin/bashread -p "請(qǐng)輸入一個(gè)字符,并按Enter鍵確認(rèn):" KEYcase "$KEY" in        [a-z]|[A-Z])                echo "您輸入的是 字母。"                ;;        [0-9])                echo "您輸入的是 數(shù)字。"                ;;        *)                echo "您輸入的是 空格、功能鍵或其他控制字符。"esac[root@linuxprobe ~]# bash Checkkeys.sh請(qǐng)輸入一個(gè)字符,并按Enter鍵確認(rèn):6您輸入的是 數(shù)字。[root@linuxprobe ~]# bash Checkkeys.sh請(qǐng)輸入一個(gè)字符,并按Enter鍵確認(rèn):p您輸入的是 字母。[root@linuxprobe ~]# bash Checkkeys.sh請(qǐng)輸入一個(gè)字符,并按Enter鍵確認(rèn):^[[15~您輸入的是 空格、功能鍵或其他控制字符。