bash高級進(jìn)程

bash腳本編程:

  過程式編程語言
      順序執(zhí)行   
      選擇執(zhí)行   
      循環(huán)執(zhí)行   
  循環(huán)執(zhí)行:必須有進(jìn)入條件和退出條件  
  • 函數(shù):結(jié)構(gòu)化編程及代碼重用

    function

選擇執(zhí)行:

if 判斷條件匪凉;then   
    條件為真的分支代碼   
fi   
    
if 判斷條件;then
    添加為真的分支代碼
else 
    條件為假的分支代碼
fi


eg:    
    新建用戶
    #!/bin/bash
    ## 如果腳本參數(shù)小于1蹬叭,則退出   
    if [ $# -lt 1 ];then
        echo "At least one argument"
        exit 1
    fi

    ## 判斷$1用戶是否存在藕咏,用戶不存在則創(chuàng)建  
    if id $1 &> /dev/null;then
        echo "$1 exists"
        exit 0
    else 
        useradd $1
        [ $? -eq 0 ] && echo "$1" | passwd --stdin $1 &> /dev/null || exit 1 
    fi 

多分支

if  判斷條件 1 ; then
    條件為真的分支代碼
elif  判斷條件 2 ; then
    條件為真的分支代碼
elif  判斷條件 3 ; then
    條件為真的分支代碼
else
    以上條件都為假的分支代碼
fi
  • 逐條件進(jìn)行判斷,第一次遇為“真”條件時(shí)秽五,執(zhí)行其分支孽查,而后結(jié)束整個(gè)if

循環(huán)

  • 循環(huán)執(zhí)行
將某代碼段重復(fù)運(yùn)行多次
重復(fù)運(yùn)行多少次:
    循環(huán)次數(shù)事先已知
    循環(huán)次數(shù)事先未知
    有進(jìn)入條件和退出條件
  • for, while, until

for循環(huán)語法:

  for  NAME in LIST;do 
      循環(huán)體   
  done
  • 執(zhí)行機(jī)制
    依次將列表中的元素賦值給“變量名”; 每次賦值后即執(zhí)行一次循環(huán)體;直到列表中的元素耗盡,循環(huán)結(jié)束

  • 循環(huán)列表生成方式:

(1)直接給出列表
(2)整數(shù)列表   
    {start..end}
    $(seq [start [step]]end)
(3)glob(統(tǒng)配路徑下的所有文件)如:*.sh
    /etc/rc.d/rc3.d/k*
(4)返回列表的命令
    $(COMMAND)
(5)變量引用:
    $@,$*

eg:

通過ping命令探測172.17.250.1-254范圍內(nèi)的所有主機(jī)的在線狀態(tài)    
#!/bin/bash 
net='172.17.253'
uphost=0
downhost=0
for i in {1..20};do
    ping -c 1 -v 1 ${net}.$i &> /dev/null
    if [ $? -eq 0 ];then
        echo "${net}.$i is up"
        let uphost++
    else 
        echo "${net}.$i is down"
        let downhost++
    fi
done 
echo "Up host:$uphost"
echo "Down host:$downhost"

while循環(huán):

while CONDITON;do
    循環(huán)體
done

CONDITION:循環(huán)控制列表:進(jìn)入循環(huán)之前坦喘,先做一次判斷盲再;每一次循環(huán)之后會再次做判斷    
    條件為“true”,則執(zhí)行一次循環(huán):直到條件測試狀態(tài)為“false”終止循環(huán)瓣铣;
    因此:CONDITION一般應(yīng)該有循環(huán)控制變量答朋,而此變量的值會在循環(huán)體不斷的被修正
進(jìn)入條件:CONDITION 為true
退出條件:CONDITION 為false

示例

1 . 求100以內(nèi)所有正整數(shù)之和

declare -i sum=0
declare -i i=1

while [ $i -le 100 ];do
    let sum+=$i
    let i++
done

echo "i=$i"
echo "Summary:$sum"

2 . 添加10個(gè)用戶

declare -i i=1
declare -i users=0
while [ $i -le 1 ];do
    if ! id user$i &> /dev/null;then
        useradd user$i
        echo "Add user:user$i"
        let users++
    fi
    let i++
done
echo "Add $users users"

3 . 通過ping命令探測172.17.253.1-254范圍的所有主機(jī)的在線狀態(tài):(用while循環(huán))

declare -i i=1
declare -i uphosts=0
declare -i downhosts=0
net='172.17.253'

while [ $i -le 20 ];do
    if ping -c 1 -w 1 $net.$i &> /dev/null;then 
        echo "$net.$i is up"
        let uphosts++
    else 
        echo "$net.$i is downhosts"
        let downhosts++
    fi 
    let i++
done 
echo "Up hosts:$uphosts"
echo "Down host:$downhosts"

4 . 打印九九乘法表:(分別使用for和while循環(huán)實(shí)現(xiàn))

for語句

    for j in {1..9};do
        for i in $(seq 1 $j);do
            echo -n -e  "${i}X${j}=$[$i*$j]\t"
        done
        echo 
    done

while語句   

    declare -i i=1
    declare -i j=1

    while [ $j -le 9 ];do
        while [ $i -le $j ];do
            echo -e -n "${i}X${j}=$[$i*$j]\t"
            let i++
        done 
        echo 
        let i=1
        let j++
    done

5 . 利用RANDOM生成10個(gè)隨機(jī)數(shù)字,輸出這10個(gè)數(shù)字棠笑,并顯示其中的最大值和最小值

#!/bin/bash
declare -i max=0
declare -i min=0
declare -i i=1

#max=$rand
#min=$rand 

while [ $i -le 9 ];do
    rand=$RANDOM
    echo $rand

    if [ $i -eq 1 ];then
        max=$rand
        min=$rand
    fi
    if [ $rand -gt $max ];then 
        max=$rand
    fi
    if [ $rand -lt $min ];then
        min=$rand
    fi
    let i++
done  

echo "MAX:$max"
echo "MIN:$min"

unil

unil COMDITION;do
    循環(huán)體
done
循環(huán)條件為:false
退出條件為:true

示例

1 . 求100以內(nèi)所有正整數(shù)之和

/bin/bash
#!
declare -i i=1
declare -i sum=0

until [ $i -gt 100 ];do
    let sum+=$i 
    let i++
done
echo "Sum:$sum" 

2 . 打印九九乘法表

#!/bin/bash
# filename timetale3.sh
# author:danran 
# time is 2017-06-22
declare -i j=1
declare -i i=1

until [ $j -gt 9 ];do
    until [ $i -gt $j ];do
        echo -n -e "${i}X${j}=$[$i*$j]\t"
        let i++
    done
    echo 
    let i=1
    let j++
done 

循環(huán)控制語句(用于循環(huán)體中)

continue [N]:提前結(jié)束第N層的本輪循環(huán)梦碗,而直接進(jìn)入下一輪判斷
    while CONDTITION1;do
        CMD1
        ...
        if CONDITION;then
            continue
        fi
        CMDn
        ...
    done




break [N]:提前結(jié)束循環(huán)
break [N] :提前結(jié)束第N 層循環(huán),
    while CONDTITION1;do
        CMD1
        ...
        if CONDITION;then
            break
        fi
        CMDn
        ...
    done

示例

求100以內(nèi)所有偶數(shù)之和,要求循環(huán)遍歷100以內(nèi)的所有正整數(shù)

#!/bin/bash
# filename even.sh
# author:danran 
# time is 2017-06-22

declare -i i=0
declare -i sum=0
until [ $i -gt 100 ];do
    let i++
    if [ $[i%2] -eq 1 ];then
        continue
    fi
    let sum+=$i
done
echo "Even sum:$sum"

創(chuàng)建死循環(huán)

while true洪规;do
    循環(huán)體
done

until false印屁;do
    循環(huán)體
done

示例

每隔3秒鐘到系統(tǒng)上獲取已經(jīng)登錄的用戶的信息:如果docker登錄了,則記錄于日志中斩例,并退出

read -p "Enter a user name: " username

while true;do
    if who | grep "^$username" &> /dev/null;then
        break
    fi
    sleep 3
done
echo "$username logged on" >> /tmp/user.log

法二
#!/bin/bash
#
read -p "Enter a user name: " username

until who | grep "^$username" &> /dev/null;do
    sleep 3
done
echo "$username logged on" >> /tmp/user.log

練習(xí)

寫一個(gè)腳本:完成如下任務(wù):

(1)顯示一個(gè)菜單   
    cpu)show cpu information:
    mem)show memory information
    disk)show disk information quit)quit
(2)提示用戶選擇選項(xiàng)     
(3)顯示用戶選擇的內(nèi)容    
進(jìn)一步的:
    用戶選擇库车,并顯示完成后不退出腳本;而是提示用戶繼續(xù)選擇顯示其內(nèi)容:直到使用quit方始退出樱拴;

法一    
#!/bin/bash
# filename sysinfo.sh
# author:danran 
# time is 2017-06-22
cat << EOF
cpu) show cpu information
mem) show memory information
disk)show disk information 
quit)quit
============================
EOF

read -p "Enter a option: " option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ];do
    read -p "Wrong option.Enter again: " option
done

if [ "$option" == 'cpu' ];then
    lscpu
elif [ "$option" == 'mem' ];then
    cat /proc/meminfo
elif [ "$option" == 'disk' ];then
    fdisk -l
else 
    echo "Quit"
    exit 0
fi

條件判斷:case語句

case 變量引用 in
PAT1)
    分支1
    ;;
PAT2)
    分支2
    ;;
...
*)
    默認(rèn)分支
    ;;
easc
  • case 支持glob 風(fēng)格的通配符:
*:任意長度任意字符
?:任意單個(gè)字符
[]:指定范圍內(nèi)的任意單個(gè)字符
a|b:a或b  

法二

#!/bin/bash
# filename sysinfo.sh
# author:danran 
# time is 2017-06-22
cat << EOF
cpu) show cpu information
mem) show memory information
disk)show disk information 
quit)quit
============================
EOF

read -p "Enter a option: " option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ];do
    read -p "Wrong option.Enter again: " option
done

case "$option" in
cpu)
    lscpu
    ;;
mem)
    cat /proc/meminfo
    ;;
disk)
    fdisk -l
    ;;
*)
    echo "Quit.."
    exit 0
    ;;
esac

練習(xí):寫一個(gè)腳本,完成如下要求

(1)腳本可接受參數(shù)洋满,start晶乔,stop,restart牺勾,status
(2)如果參數(shù)非此四者之一正罢,提示使用格式后報(bào)錯(cuò)退出
(3)如果是start,則創(chuàng)建/var/lock/subsys/SCRIOT_NAME,并顯示“啟動(dòng)成功”
    考慮:如果事先已經(jīng)啟動(dòng)過一次驻民,該如何處理
(4)如果是stop:則刪除/vat/lock/subsys/SCRIPT_NAME,并顯示“停止完成”
    考慮:如果事先已經(jīng)停止過了翻具;g該如何處理
(5)如果是restart,則先stop回还,再start裆泳;
    考慮:如果本來沒有start,再如何處理   
(6)如果是status柠硕,則
    如果/var/lock/subsys/SCRIPT_NAME文件存在工禾,則顯示“SCRIPT_NAME is running...”;
    如果/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示“SCRIPT_NAME is stopped...”;
其中:SCRIPT_NAME為當(dāng)前腳本名  

循環(huán)控制shift命令

shift [n]

用于將參量列表list 左移指定次數(shù)蝗柔,缺省為左移一次闻葵。

  • 參量列表list一旦被移動(dòng),最左端的那個(gè)參數(shù)就從列表中刪除癣丧。while到循環(huán)遍歷位置參量列表時(shí)槽畔,常用到shift
  • ./doit.sh a b c d e f g h
  • ./shfit.sh a b c d e f g h

示例:

doit.sh
    #!/bin/bash
    # Name:doit.sh
    # Purpose:shift through command line arguments
    # Usage:doit.sh [args]
    while [ $# -gt 0 ] # or (( $# > 0 ))
    do
        echo $*
        shift
    done

shift.sh
    #!/bin/bash
    #step through all the positional parameters
    until [ -z "$1" ]
    do
        echo "$1"
        shift
    done
    echo

特殊用法

  • while 循環(huán)的特殊用法(遍歷文件的每一行):
while read line; do
    循環(huán)體
done < /PATH/FROM/SOMEFILE
  • 依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line
  • 練習(xí)
    掃描/etc/passwd文件每一行,如發(fā)現(xiàn)GECOS 字段為空胁编,則填充用戶名和單位電話為62985600厢钧,并提示該用戶的GECOS信息修改成功。
  • 示例:
#掏呼!/bin/bash
while read passwdline
do
    uid=`echo $passwdline | cut -d: -f3`
    user=`echo $passwdline | cut -d: -f1`
    [ "uid" -ge 1000 ] && echo "$user is common user" || echo "$user is system user"
done < /etc/passwd
unset passwdline uid user
  • 雙小括號方法坏快,即((…))格式,也可以用于算術(shù)運(yùn)算
  • 雙小括號方法也可以使bash Shell 實(shí)現(xiàn)C 語言風(fēng)格的變量操作
I=10
((I++))
  • for循環(huán)的特殊格式:
for (( 控制變量初始化; 條件判斷表達(dá)式; 控制變量的修正表達(dá)式))
do
    循環(huán)體
done
  • 控制變量初始化:僅在運(yùn)行到循環(huán)代碼段時(shí)執(zhí)行一次
  • 控制變量的修正表達(dá)式:每輪循環(huán)結(jié)束會先進(jìn)行控制變量修正運(yùn)算憎夷,而后再做條件判斷
  • 示例:求100以內(nèi)的所有正奇數(shù)之和
#莽鸿!/bin/bash
sum=0
for i in {1..100..2};do
    let sum+=i
done
echo sum=$sum

#!/bin/bash
for ((sum=0,i=1;i<=100;i+=2 ));do
    let sum+=i
done
echo sum=$sum

#!/bin/bash
sum=0;
i=1;
while [ $i -le 100 ];do
    let sum+=1
    let i+=2
done
echo sum=$sum

2 . 求100以內(nèi)的正整數(shù)之和

#!/bin/bash
declare -i sum=0
for ((i=1;i<=100;i++));do
    let sum+=$i
done
echo "Sum:$sum"

3 . 打印九九乘法表:

#!/bin/bash
# filename multi.sh
# author:danran 
# time is 2017-06-22
for ((j=1;j<=9;j++));do
    for((i=1;i<j;i++));do
        echo -e -n "$[i]X$[j]=$[$i*$j]\t"
    done
    echo
done

select循環(huán)與菜單

select variable in list
do
    循環(huán)體命令
done
  • select循環(huán)主要用于創(chuàng)建菜單,按數(shù)字順序排列的示菜單項(xiàng)將顯示在標(biāo)準(zhǔn)錯(cuò)誤上,并顯示PS3提示符祥得,等待用戶輸入
  • 用戶輸入菜單列表中的某個(gè)數(shù)字兔沃,執(zhí)行相應(yīng)的命令
  • 用戶輸入被保存在內(nèi)置變量REPLY中

select與case

  • select用是個(gè)無限循環(huán),因此要記住用 break命令退用出循環(huán)级及,或用exit按命令終止腳本乒疏。也可以按ctrl+c退出循環(huán)
  • select和經(jīng)常和case聯(lián)合使用
  • 與for循環(huán)類似,可以省略inlist饮焦,此時(shí)使用位置參量
  • 示例:創(chuàng)建菜單
#怕吴!/bin/bash
PS3="Please choose your menu: "
select menu in work home office exit 
do
    case $menu in 
    work)
        echo "go work"
        ;;
    home)
        echo "go home"
        ;;
    office)
        echo "go office"
        ;;
    *)
        echo unknow
        break
    esac
    echo your choose is $menu
    echo "Your input is $REPLY"
done

信號捕捉trap

  • trap ' 觸發(fā)指令' 信號
    自定義進(jìn)程收到系統(tǒng)發(fā)出的指定信號后,將執(zhí)行觸發(fā)指令县踢,而不會執(zhí)行原操作
  • trap '' 信號
    忽略信號的操作
  • trap '-' 信號
    恢復(fù)原信號的操作
  • trap -p
    列出自定義信號操作

trap示例

#!/bin/bash
trap 'echo “signal:SIGINT"' int
trap -p  \\打印trap自定義命令
for((i=0;i<=10;i++))
do
    sleep 1
    echo $i
done

trap '' int  //int信號設(shè)置為空
trap -p   \\打印trap自定義命令
for((i=11;i<=20;i++))
do
    sleep 1
    echo $i
done

trap '-' int  //恢復(fù)int信號的操作
trap -p   \\打印trap自定義命令
for((i=21;i<=30;i++))
do
    sleep i
    echo $i
done
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末转绷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子硼啤,更是在濱河造成了極大的恐慌议经,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谴返,死亡現(xiàn)場離奇詭異煞肾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嗓袱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門籍救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人渠抹,你說我怎么就攤上這事钧忽。” “怎么了逼肯?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵耸黑,是天一觀的道長。 經(jīng)常有香客問我篮幢,道長大刊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任三椿,我火速辦了婚禮缺菌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搜锰。我一直安慰自己伴郁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布蛋叼。 她就那樣靜靜地躺著焊傅,像睡著了一般剂陡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狐胎,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天鸭栖,我揣著相機(jī)與錄音,去河邊找鬼握巢。 笑死晕鹊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的暴浦。 我是一名探鬼主播溅话,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歌焦!你這毒婦竟也來了公荧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤同规,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后窟社,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體券勺,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年灿里,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了关炼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匣吊,死狀恐怖儒拂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情色鸳,我是刑警寧澤社痛,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站命雀,受9級特大地震影響蒜哀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吏砂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一撵儿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狐血,春花似錦淀歇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春浴鸿,著一層夾襖步出監(jiān)牢的瞬間井氢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工岳链, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留花竞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓掸哑,卻偏偏與公主長得像约急,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子苗分,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 流程控制過程式編程語言:順序執(zhí)行選擇執(zhí)行循環(huán)執(zhí)行 一.條件選擇if語句 類型:選擇執(zhí)行 ?注意:if語句可嵌套 ?...
    楠人幫閱讀 481評論 0 1
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法厌蔽,類相關(guān)的語法,內(nèi)部類的語法摔癣,繼承相關(guān)的語法奴饮,異常的語法,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • Bash內(nèi)置基本變量 PWD : 顯示當(dāng)前的工作目錄 OLDPWD : 顯示上一次的工作目錄 ~:用戶家目錄 - ...
    魏鎮(zhèn)坪閱讀 1,514評論 0 6
  • 早起的鳥兒有食吃投剥。2017已經(jīng)過去四分之一,不知道大家的目標(biāo)實(shí)現(xiàn)了多少呢担孔?無論是相對穩(wěn)定的上班一族江锨,還是自由職業(yè)為...
    奮斗的番茄閱讀 160評論 0 0
  • 淅淅瀝瀝的雨 雨天 有人說找個(gè)咖啡店 靠窗坐 手托著下巴 眼睛望向窗外 看著窗戶上劃過的雨痕 覺得發(fā)呆也很幸福 而...
    南宮紫雪閱讀 227評論 0 0