shell編程企業級實戰(2)

Vim配置文件.vimrc

vim配置文件

if 條件語句

if是最多見的條件判斷語句web

 

 

例1:若是不存在/backup目錄就建立。
[root@web-01 /server/tools]# vim 07-01.sh
#!/bin/bas
path=/backup
[ -d $path ] || mkdir $path -p
# 至關於
# :冒號表示什麼也不幹
if [ -d $path ]
then
        :
else
        mkdir $path -p
fi
# 或者
[ !-d $path ] && mkdir /backdir -p
# 至關於
if [ !-d $path ]
then
        mkdir /backdir -p
if
"07-01.sh" 18L, 248C writte
vim命令:替換:%s#/backup#$path#g
例2:開發Shell腳本判斷系統剩餘內存的大小,若是低於100MB就提示內存不足,不然提示內存充足。 考查if雙分支: 分析:
1)提取系統內存。 2)if判斷, [root@web01 07]# cat 07_02.sh #!/bin/bash ############################################################## # File Name: 07_02.sh # Version: V1.0 # Author: pizza # Created Time : 2018-06-06 22:58:54 # Description: ############################################################## mem=`free -m|awk 'NR==3{print $NF}'` if [ $mem -lt 1000 ] then echo "內存嚴重不足。" else echo "內存還夠" fi

在第一章的中添加了內存不足發郵件的例子
例3:分別使用變量定義、read讀入及腳本傳參方式實現比較2個整數的大小。 1)變量定義: a=6 b=2 2)read讀入: read -p "請輸入兩個數字:" a b 3)傳參: 分析: 大於 等於 小於 #!/bin/bash
##############################################################
# File Name: 07-03.sh
# Version: V1.0
# Author: pizza
# Created Time : 2019-03-28 21:20:46
# Description:
##############################################################
# 第一種,傳參
a=6
b=7
# 第二種,read
read -p "請輸入兩個數字" a b
# 第三種,參數
$a=$1
$b=$2
# 判斷輸入
# 一、判斷數字是否是夠,判斷b是否是空,或者使用$#
# 二、判斷是否是整數,利用expr
# 三、

if [ $a -gt $b ]
then
    echo "$a>$b"
elif [ $a -lt $b ]
then
    echo "$a<$b"
else
    echo "$a=$b"
fi

例4:打印一個菜單以下,當用戶選擇對應的數字時,就執行對應項的應用。
1.install lamp 2.install lnmp 3.exit 第一章已講解: bash內置核心命令read的企業級應用實踐 read企業應用 [root@web01 scripts]# cat select1.sh #!/bin/bash cat <<EOF 1.install lamp 2.install lnmp 3.exit EOF read -p "請選擇一個序號(必須是數字):" num #1.判斷是否爲整數 expr 2 + $num &>/dev/null if [ $? -ne 0 ] then echo "Usage:$0 {1|2|3}" exit 1 fi #2.判斷執行處理 if [ $num -eq 1 ] then echo "install lamp..." elif [ $num -eq 2 ] then echo "install lnmp..." elif [ $num -eq 3 ] then echo "bye." exit else echo "Usage:$0 {1|2|3}" exit 1 fi

 

Shell函數的知識與實踐

函數的做用就是將程序裏屢次被調用的相同代碼組合起來,併爲其取個名字。其餘全部想重複調用這部分代碼的複方都只須要調用這個這個名字就能夠了。當須要修稿這部分重複代碼的時候,也只須要改變函數內的一份代碼便可實現全部的修改,也能夠把函數獨立寫到文件裏面,當須要調用的時候,再加載進來。面試

 

函數的語法體算法

 

 

oldboy() {
    echo "I am oldboy."
}
function oldgirl {
    echo "I am oldgirl."
}
test() {
    echo "Hello world."
}
oldboy
oldgirl

[root@web-01 ~]# sh test_hanshu.sh
I am oldboy.
I am oldgirl.
Hello world.
[root@web-01 ~]#

 

向函數傳參shell

帶參數的函數編寫執行
oldboy() {
    echo "I am $1."
}
oldboy oldboy
將函數傳參轉爲腳本傳參
oldboy() {
    echo "I am $1."
}
oldboy $1

函數和執行函數分離
./etc/init.d/function
pizza $1

 

Shell函數的執行注意事項編程

 

企業案例:經過腳本傳參的方式,檢查Web 網站URL是否正常。vim

wget命令:
--spider 模擬爬蟲
-q 安靜訪問
-o /dev/null 不輸出
-T --timeout 超時時間
-t --tries 重試次數
[root@web01 ~]# wget --spider -T 5 -q -o /dev/null -t 2 www.baidu.com
[root@web01 ~]# echo $?
0
curl命令:
-I 看響應頭
-s 安靜的 安靜模式。不顯示進度表或錯誤信息。使cURL 不反饋信息。
-o /dev/null 不輸出
-w %{http_code} 返回狀態碼,200
-m 超時時間
[root@web01 ~]# curl www.baidu.com -s &>/dev/null [root@web01 ~]# echo $? 0 [root@web01 ~]# curl -I -m 5 -s -w "%{http_code}\n" -o /dev/null www.baidu.com 200 不用函數的實現寫法 #!/bin/sh if [ $# -ne 1 ] then echo $"usage:$0 url" exit 1 fi wget --spider -q -o /dev/null --tries=1 -T 5 $1 #<==-T指定超時時間,這裏的$1爲腳本的參數。 if [ $? -eq 0 ] then echo "$1 is yes." else echo "$1 is no." fi 高端專業的函數寫法: [root@oldboy ~]# cat checkurl.sh #!/bin/bash ############################################################## # File Name: checkurl.sh # Version: V1.0 # Author: oldboy # Organization: www.oldboyedu.com # Created Time : 2018-06-07 18:29:19 # Description: ############################################################## usage(){ echo "Usage:$0 url" exit 1 } checkurl(){ wget -q -o /dev/null -t 2 -T 5 $1 if [ $? -eq 0 ] then echo "$1 is ok" else echo "$1 is fail" fi } main(){ if [ $# -ne 1 ] then usage fi checkurl $1 } main $* [root@oldboy scripts]# cat 8_5_1.sh #!/bin/sh function usage() { #<==幫助函數 echo $"usage:$0 url" exit 1 } function check_url() { #<==檢測URL函數。 wget --spider -q -o /dev/null --tries=1 -T 5 $1 #<==這裏的$1就是函數傳參。 if [ $? -eq 0 ] then echo "$1 is yes." else echo "$1 is no." fi } function main() { #<==主函數。 if [ $# -ne 1 ] #<==若是傳入的多個參數,則打印幫助函數,提示用戶。 then usage fi check_url $1 #<==接收函數的傳參,即把結尾的$*傳到這裏。 } main $* #<==這裏的$*就是把命令行接收的全部參數做爲函數參數傳給函數內部,經常使用手法。

 

 

CASE結構條件句

幾乎全部的case均可以用if替代
case "$1" in
    1)
    dddd
    ;;
    2)
    dddd
    ;;
    *)
    dddd
esac

企業應用:
啓動腳本
read 讀入 菜單選擇。

範例9_2:執行shell腳本,打印一個以下的水果菜單:
1.apple
2.pear
3.banana
4.cherry
當用戶輸入對應的數字選擇水果的時候,告訴他選擇的水果是什麼,並給水果單詞加上一種顏色(隨意),要求用case語句實現。
範例9_3:給內容加不一樣的顏色。
內容的顏色用數字表示,範圍爲30-37,每一個數字表明一種顏色。代碼以下:
echo -e "\033[30m 黑色字 \033[0m" #<==30m表示黑色字。
echo -e "\033[31m 紅色字 \033[0m" #<==31m表示紅色字。
echo -e "\033[32m 綠色字 \033[0m" #<==32m表示綠色字。
echo -e "\033[33m 棕色字 \033[0m" #<==33m表示棕色字(brown),和黃色字相近。
echo -e "\033[34m 藍色字 \033[0m" #<==34m表示藍色字。
echo -e "\033[35m 洋紅字 \033[0m" #<==35m表示洋紅色字(magenta),和紫色字相近。
echo -e "\033[36m 藍綠色 \033[0m" #<==36m表示藍綠色字(cyan),和淺藍色字相近。
echo -e "\033[37m 白色字 \033[0m" #<==37m表示白色字。
說明:不一樣的數字對應的字體顏色,見系統幫助(來源man console_codes命令的結果)。
範例9_6: 給輸出的字符串加不一樣的背景顏色。
字的背景顏色對應的數字範圍爲40-47,代碼以下。
echo -e "\033[40;37m 黑底白字\033[0m"   #<==40m表示黑色背景。
echo -e "\033[41;37m 紅底白字\033[0m"   #<==41m表示紅色背景。
echo -e "\033[42;37m 綠底白字\033[0m"   #<==42m表示綠色背景。
echo -e "\033[43;37m 棕底白字\033[0m"   #<==43m表示棕色背景(brown),和黃色背景相近。
echo -e "\033[44;37m 藍底白字\033[0m"   #<==44m表示藍色背景。
echo -e "\033[45;37m 洋紅底白字\033[0m"  #<==45m表示洋紅色背景(magenta),和紫色背景相近。
echo -e "\033[46;37m 藍綠底白字\033[0m"   #<==46m表示藍綠色背景(cyan),和淺藍色背景相近。
echo -e "\033[47;30m 白底黑字\033[0m"    #<==47m表示白色背景。

建立case3.sh,定義函數 ,執行函數color $*
建立case4.sh,用.或者source調用函數,打印菜單,輸入數字,顯示不一樣顏色的字體 範例9_10:利用case語句開發Rsync服務啓動中止腳本,本例採用case語句以及新的思路來實現。 分析: 啓動: rsync
--daemon 中止: pkill rsync killall rsync kill 進程號 ---->最專業的方法 /etc/init.d/rsyncd {start|stop|restart} case

 rsync.sh簡單版數組

case "$1" in
    start)
        rsync --deamon
        if [ $? -eq 0 ]
        then
            echo "rsync startup ok"
        else
            echo "rsync startup fail"
        fi
        ;;
    stop)
        killall rsync
        if [ $? -eq 0 ]
        then
            echo "rsync stop ok"
        else
            echo "rsync stop fail"
        fi
        ;;
    restart)
        killall rsync && sleep 1 && rsync --deamon
        if [ $? -eq 0 ]
        then
            echo "rsync restart ok"
        else
            echo "rsync restart fail"
        fi
        ;;

    *)
        echo "usage:$0 {start|stop|restart}"
        exit 1
esac

 

升級版bash

 start(){                                                                                                        
     rsync --deamon
     retval=$?
     if [ $retval -eq 0 ]
     then
         echo "rsync startup ok"
         return $retval
     else
         echo "rsync startup fail"
         return $retval
     fi
 }
 stop(){
     killall rsync
     retval=$?
     if [ $? -eq 0 ]
     then
          echo "rsync stop ok"
                                                                                                  9,1           Top
        return $retval
    else
        echo "rsync restart fail"
        return $retval
    fi  
    }   
case "$1" in
    start)
        start
        # 爲了向外傳值
        retval=$?
        ;;  
    stop)
        stop
        retval=$?
        ;;  
    restart)
        restart
        retval=$?
        ;;  

    *)  
        echo "usage:$0 {start|stop|restart}"
        exit 1
esac

 

想要使用chkconfig(man ckhconfig),找到這些信息網絡

RUNLEVEL FILES
       Each service which should be manageable by chkconfig needs two or more commented lines added to its init.d
       script. The first line tells chkconfig what runlevels the service should be started in by default, as well
       as the start and stop priority levels. If the service should not, by default, be started in any runlevels,
       a  -  should  be used in place of the runlevels list.  The second line contains a description for the ser‐
       vice, and may be extended across multiple lines with backslash continuation.

       For example, random.init has these three lines:
       # chkconfig: 2345 20 80  表示在2345這幾個啓動級別上 啓動順序排20 中止順序排80
       # description: Saves and restores system entropy pool for \
       #              higher quality random number generation.

 

在腳本首行加入app

#!/bin/bash
# chkconfig: 2345 20 80
# description: rsync start stop and restart   

 

將腳本移動到/etc/init.d/下,並添加執行權限,添加到chkconfig中才能使用

[root@web-01 /server/tools]# mv /etc/init.d/rsync_up.sh /etc/init.d/rsyncd
[root@web-01 /server/tools]# chmod +x /etc/init.d/rsyncd
[root@web-01 /server/tools]# chkconfig --list rsyncd

Note: This output shows SysV services only and does not include native
      systemd services. SysV configuration data might be overridden by native
      systemd configuration.

      If you want to list systemd services use 'systemctl list-unit-files'.
      To see services enabled on particular target use
      'systemctl list-dependencies [target]'.

service rsyncd supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add rsyncd')
[root@web-01 /server/tools]# chkconfig --add rsyncd
[root@web-01 /server/tools]# chkconfig --list rsyncd

Note: This output shows SysV services only and does not include native
      systemd services. SysV configuration data might be overridden by native
      systemd configuration.

      If you want to list systemd services use 'systemctl list-unit-files'.
      To see services enabled on particular target use
      'systemctl list-dependencies [target]'.

rsyncd             0:off    1:off    2:on    3:on    4:on    5:on    6:off

 

更好一些,調用了系統函數,action。並優化了重複中止的輸出 

#!/bin/bash                                                       
# chkconfig: 2345 20 80
# description: rsync start stop and restart
##############################################################
# File Name: syncd.sh
# Version: V1.0
# Author: pizza
# Created Time : 2019-03-29 22:06:46
# Description:
##############################################################
. /etc/init.d/functions
start(){
    rsync --deamon
    retval=$?
    if [ $retval -eq 0 ]
    then
        action  "rsync startup ok" /bin/true
        return $retval
    else
        action "rsync startup fail" /bin/false
        return $retval
    fi
}
                                                1,1           Top
        return $retval
    fi
    }
case "$1" in
    start)
        start
        # 我了向外傳值
        retval=$?
        ;;
    stop)
        stop
        retval=$?
        ;;
    restart)
        restart
        retval=$?
        ;;

    *)
        echo "usage:$0 {start|stop|restart}"
        exit 1
esac
     

 

開發和系統媲美的腳本

跟完善的查看企業實踐題第11題-製做MySQL腳本

                                                         92,0-1        Bot
#!/bin/bash
# chkconfig: 2345 20 80
# description: rsync start stop and restart
##############################################################
# File Name: syncd.sh
# Version: V1.0
# Author: pizza
# Created Time : 2019-03-29 22:06:46
# Description:
##############################################################
# 定義鎖文件
lockfile=/var/lock/subsys/rsyncd
# 定義變量,指定rsyncd的的pid,是須要本身rsync的conf中去建立

#[root@web-01 /server/tools]# vim /etc/rsyncd.conf
#pid file=/var/run/rsyncd.pid    

srsync_pid_file_path=/var/run/rsyncd.pid
. /etc/init.d/functions
start(){
    rsync --deamon
    retval=$?
    if [ $retval -eq 0 ]
    then
        action  "rsync startup ok" /bin/true
        touch $lockfile
        return $retval
    else
        action "rsync startup fail" /bin/false
        return $retval
    fi
}
stop(){
    # 爲了在重複中止操做的時候,不提示,將其扔到黑洞
    if test -s "$rsyncd_pid_file_path"
    then
        rsyncd_pid=`cat $rsyncd_pid_file_path`
        # 判斷進程號是否是真實存在
        if (kill -0 $rsyncd_pid &>/dev/null)
        then
            kill $rsyncd_pid

            retval=$?
            if [ $? -eq 0 ]
            then
                action "rsync stop ok" /bin/true
                rm -f $lockfile
                return $retval
            else
                action "rsync stop fail" /bin/false
                return $retval
            fi
        else
            echo "rsyncd process is not exist."
            return 2
        fi
    else
        echo "$srsync_pid_file_path is not exits,or rsyncd doesnot start"
    fi
}
restart(){
    killall rsync && sleep 1 && rsync --deamon
    retval=$?
    if [ $? -eq 0 ]
    then
        action "rsync restart ok" /bin/true
        return $retval
    else
        action "rsync restart fail" /bin/false
        return $retval
    fi
    }
case "$1" in
    start)
        start
        # 我了向外傳值
        retval=$?
        ;;
    stop)
        stop
        retval=$?
        ;;
    restart)
        restart
        retval=$?
        ;;

    *)
        echo "usage:$0 {start|stop|restart}"
        exit 1
esac
  

 

case總結

一、case語句和if條件句的使用性

case語句比較適合變量較少且爲固定的數字或者字符串集合的狀況(非不肯定內容,如範圍)

二、if和case的經常使用應用場景

case只要寫服務的啓動腳本,通常狀況下,傳參不一樣且具備少許的字符串,其使用範圍較窄

if就是取值判斷、比較,應用比case更廣,幾乎全部的case語句均可以用if條件語句實現。

三、case語句的特色和優點

它至關於多分支的if/elif/else語句,可是case語句的優點是更規範。易讀

 

while循環

循環語句命令經常使用於重複執行一條指令或一組指令,直到條件不知足中止,Shell腳本語言的循環語句常見的有while、until、for以及select循環語句。 while循環語句主要用來重複執行一組命令或語句,在企業實際應用中,經常使用於守護進程或持續運行的程序,除此之外,大多數循環都會用後文即將講解 的for循環語句。

while true
do
    uptime >> /tmp/uptime.log
    sleep 2 # 暫停2s
    usleep 2000 # 微秒                                                                                              
done

 

腳本進程管理命令

 

    後臺運行  &、nohup、screen(運維人員)

 爲何要用後臺運行,防止你在執行重要命令的時候,網絡宕機

進程管理的其餘常見命令

範例1:請使用while循環對下面的腳本進行修改,是的當執行腳本時,每次執行完腳本後,不退出腳本,而是提示用戶輸入

while true
do
    read -p "請輸入兩個數字:" a b
    if [ -z $b ]
    then                                                                                
        echo "請輸入兩個數字"
        continue
    fi
    expr 10 + $a + $b &>/dev/null
    if [ $? -ne 0 ]
    then
        echo "請輸入兩個數字"
        continue
    fi
    echo "a+b=$(($a+$b))"
done

 

範例2:猜數字遊戲。首先讓系統隨機生成一個數字,給這個數字定一個範圍(1-60),讓用戶輸入猜的數字,對輸入進行判斷,若是不符合要求,就給予高或低的提示,猜對後則給出猜對用的次數,請用while語句實現。

提示:能夠賦予一個猜水果的價格遊戲。

1、給數字定範圍(1-60)
RANDOM隨機數,它的範圍是0-32767
[root@web-01 /server/tools]# echo $RANDOM
9279
爲隨機數取模。控制在1-60
[root@web-01 /server/tools]# echo $((RANDOM%60))
11
2、用戶輸入數字
read -p 「請輸入數字:」 num

3、對比,直到正確才推出
while 
四、代碼:
random="$(($RANDOM%60))"
#作計數
count=0
echo $random
while true
do
    read -p "請輸入數字:" num
    ((count++))
    if [[ $num -lt $random ]]
    then
        echo "低了"
        continue
    elif [[ $num -gt $random ]]
    then
        echo "高了"
        continue
    elif [[ $num -eq $random ]]                                          
    then
        echo "恭喜你,猜對了,一共猜了$count次"
        exit 0
    else
        echo "請輸入數字"
    fi
done

還能夠加入函數,其餘的限制內判斷,使腳本更完善

 

範例3:分析Apache訪問日誌(access_2010-12-8.log)日誌每行訪問字節數對應字段數字相加,計算出的訪問量。給出實現程序,請用while循環實現。(3分鐘)

方式1:在while循環結尾done經過輸入重定向指定讀取的文件。
while read line
do
    cmd
done<FILE
方式2:使用cat讀取文件內容,而後經過管道進入while循環處理。
cat FILE_PATH|while read line
do
    cmd
done
方式3:採用exec讀取文件後,而後進入while循環處理。
exec <FILE
sum=0
while read line
do
    cmd
done

 

體驗

while read line
do
    echo $line
    sleep 1
done < ./while_01.sh                                                     
~                                                                        
~                                                                        
                                                                      
"while_readline.sh" [New] 13L, 320C written            
[root@web-01 /server/tools]# sh while_readline.sh
#!/bin/bash   
##############################################################
# File Name: while_01.sh
# Version: V1.0
# Author: pizza
# Created Time : 2019-03-30 07:19:26
# Description:
##############################################################
while true
do
uptime >> /tmp/uptime.log
sleep 2 # 暫停2s
usleep 2000 # 微秒
done

 

體驗2

[root@web-01 /server/tools]# seq 10 >>num.log
腳本
sum=0
while read line
do
    ((sum+=line))

done<./num.log
echo $sum     
執行
[root@web-01 /server/tools]# sh while_num_add.sh
55

 

答案

sum=0
awk '{print $10}' access_2010-12-8.log |grep -v -|while read line
do
    ((sum+=line))
done
echo sum 
# 已經計算了,可是最後的結果是0
# 這是由於執行了子shell
# 使用下面的方法能夠成功輸出                                             

sum=0
awk '{print $10}' access_2010-12-8.log |grep -v - > any_sum.log
do
    ((sum+=line))
done<./any_sum.log
echo sum 

 

 小結

一、while循環的特長是執行守護進程,以及實現咱們但願循環不退出持續執行的應用

擅長用於頻率小於1分鐘循環處理,其餘的while循環幾乎均可以被for以及定時任務crond替代

二、if、for最經常使用,而後是while(守護進程),case(服務啓動腳本)

Shell腳本中各個語句的使用場景

  一、條件表達式,用於簡短的條件判斷及輸出(文件是否存在,字符串是否爲空)

  二、if取值判斷,多用於不一樣值數量較少的狀況

  三、for正常的循環應用處理,最經常使用

  四、while多用於守護進程,無限循環(要加sleep,usleep,控制pinlv)應用

  五、case 多用於服務啓動腳本,打印菜單可用select語句,不過不多用,都用cat的here文檔方法替代

  六、函數用途主要指編碼邏輯清晰,減小重複語句開發

for循環

for循環語句和while循環語句相似,但for循環語句主要用於執行次數有限的循環,而不是用於守護進程以及無限循環。for循環語句常見的語法有兩種, 下面將在不一樣的語法中對for循環語句進行詳盡的講解。

..

範例1:用for循環豎向打印一、234、5共5個數字。
範例2:經過開發腳本實現僅設置sshd rsyslog crond network sysstat服務開機自啓動。
範例3:計算從1加到100之和。
範例4:在Linux下批量修改文件名,將文件名中的「_finished」去掉。
準備測試數據,以下。
[root@oldboy test]# mkdir /oldboy -p
[root@oldboy test]# cd /oldboy
[root@oldboy oldboy]# touch stu_102999_1_finished.jpg stu_102999_2_finished.jpg stu_102999_3_finished.jpg 
[root@oldboy oldboy]# touch stu_102999_4_finished.jpg stu_102999_5_finished.jpg
[root@oldboy oldboy]# ls -l
總用量 0
-rw-r--r-- 1 root root 0 9月   5 10:43 stu_102999_1_finished.jpg
-rw-r--r-- 1 root root 0 9月   5 10:43 stu_102999_2_finished.jpg
-rw-r--r-- 1 root root 0 9月   5 10:43 stu_102999_3_finished.jpg
-rw-r--r-- 1 root root 0 9月   5 10:43 stu_102999_4_finished.jpg
-rw-r--r-- 1 root root 0 9月   5 10:43 stu_102999_5_finished.jpg

ls *.jpg|awk -F "_finished" '{print "mv",$0,$1$2}'|bash
rename "_finished" "" *.jpg
for file in `ls ./*.jpg`
do
    mv $file `echo ${file/_finished/}`
done

 

範例1答案

for n in 1 2 3 4 5  或者 {1..5}  或者seq 5 
do
    echo $n
done
echo "---------"
for ((i=1;i<=5;i++))
do
    echo $i
done                                                                                                                                                                                                                                                                               
"for_printnum.sh" [New] 18L, 350C written              
[root@web-01 /server/scripts]# sh for_printnum.sh
1
2
3
4
5
---------
1
2
3
4
5

 

範例2答案

for name in sshd rsyslog crond network sysstat
do
    echo "chkconfig $name on"                                            
done

至關於在命令行執行
[root@web-01 /server/scripts]# chkconfig |grep 3:on |awk '{print "chkconfig",$1,"off"}'|bash

 

範例3

1、for循環
2、while循環
3、算法 

 

範例4

1mv $file 'echo ${file/_finished/}'
2、不用for循環
[root@web-01 /server/scripts]# ls *.jpg|awk -F "_finished" '{print $0,$1$2}'
3、rename  from  to  file
rename  _finished ""  *.jpg

 

循環控制語句break、continue、exit、return

上述命令中breakcontinue在條件語句及循環語句(forwhileif等)中用於控制程序的走向,

exit用於終止全部語句並退出當前腳本,除此以外,exit還能夠返回上一次程序或命令的執行狀態值給當前Shell

return相似exit,只不過return用於函數內部返回函數執行的狀態值

break n    若是省略n表示跳出整個循環,n 表示跳出循環的層數
continue n    若是省略n表示跳過本次循環,忽略本次循環的剩餘代碼,進入循環的下一次循環。n 表示退到第n層繼續循環
exit n    退出當前shell程序,n爲上一次程序執行的狀態返回值。n也能夠省略,再下一個shell裏可經過$?接收exit n的n值
return n    用於在函數裏,做爲函數的返回值,用於判斷函數執行是否正確。再下一個shell裏可經過$?接收exit n的n值

 

 

Shell編程數組應用實踐

爲何會產生shell數組

一般在開發Shell腳本時,咱們定義變量採用的形式爲a=1;b=2;c=3,可若是有多個變量呢?這時再一個一個定義很費勁,而且多個不肯定的變量內容,也難以進行變量定義,此外快速讀取不一樣變量的值也是一件很痛苦的事情,因而數組就誕生了,就是爲了解決上述問題而來的

什麼是Shell數組

 

若是讀者有過其餘語言的編程經歷,那麼想必會熟悉數組的概念。簡單地說,Shell的數組就是把有限個元素(變量或字符內容)用一個名字命名,而後用編號對它們進行區分的元素集合。這個名字就稱爲數組名,用於區分不一樣內容的編號就稱爲數組下標。組成數組的各個元素變量稱爲數組的元素,有時也稱爲下標變量。

 

有了Shell數組後,就能夠用相同名字引用一系列變量及變量值,並經過數字(索引)來識別使用它們。在許多場合,使用數組能夠縮短和簡化程序開發。


數組的本質仍是變量,是特殊的變量形式
array=(1 2 3 4 5)

 

Shell數組的定義*****
    方法1:推薦,用小括號把變量值括起來賦值給數組變量,中間用空格分割
    array=(one two three four)
    方法2:用小括號把變量值括起來,同時採用鍵值對的形式賦值
    array=([0]=one [1]=two [2]=three [3]=four)
    方法3:經過分別定義數組變量的方式
    [root@web01 ~]# array[0]=one
    [root@web01 ~]# array[1]=two
    [root@web01 ~]# array[2]=three
    [root@web01 ~]# array[3]=four
    [root@web01 ~]# echo ${array[@]}
    one two three four
    方法4:命令的結果放到數組裏,推薦。動態定義數組變量,使用命令的輸出結果做爲數組的內容
    array=(`ls /server/scripts`)

說明:還可使用declare -a array來定義數組類型,可是比較少這樣用。


操做數組元素
打印單個數組元素用${數組名[下標]},當未指定數組下標時,數組的下標是從0開始。
使用*或者@能夠獲得整個數組內容。
用${#數組名[@或*]}能夠獲得數組長度,這和前文講解的變量子串知識是同樣的,由於數組也是變量,只不過是特殊的變量,所以也適合變量的子串替換等知識。

讀取數組內容:*****
[root@web01 ~]# array=( 1 2 3 4 5)
[root@web01 ~]# echo ${array[0]}
1
[root@web01 ~]# echo ${array[1]}
2
[root@web01 ~]# echo ${array[2]}
3
[root@web01 ~]# echo ${array[3]}
4
[root@web01 ~]# echo ${array[4]}
5
[root@web01 ~]# echo ${array[5]}

[root@web01 ~]# echo ${array[*]}
1 2 3 4 5
[root@web01 ~]# echo ${array[@]}
1 2 3 4 5
[root@web01 ~]# echo ${#array[@]}
5
[root@web01 ~]# echo ${#array[*]}
5

給數組增長內容:
[root@web01 ~]# array[5]=oldboy   <==增長下標爲5的數組元素。
[root@web01 ~]# echo ${#array[*]}
6
[root@web01 ~]# echo ${array[*]}
1 2 3 4 5 oldboy

刪除數組元素:
[root@web01 ~]# unset array[1]
[root@web01 ~]# echo ${array[*]}
1 3 4 oldboy
[root@web01 ~]# unset array[0]
[root@web01 ~]# echo ${array[*]}
3 4 oldboy

數組賦值:
[root@web-01 /server/scripts]# array[4]=999
[root@web-01 /server/scripts]# echo ${array[*]}
1 2 3 4 999 6

數組的刪除:
由於數組本質上仍是變量,所以可經過「unset 數組[下標]」清除相應的數組元素,
若是不帶下標,表示清除整個數組的全部數據。
[root@web-01 /server/scripts]# unset array[1]  刪除單個元素
[root@web-01 /server/scripts]# echo ${array[*]}
1 3 4 999 6
[root@web-01 /server/scripts]# unset array    刪除整個數組
[root@web-01 /server/scripts]# echo ${array[*]} 沒有數據輸出了

數組內容的截取和替換:
這裏和前文變量子串的替換是同樣的,由於數組是特殊的變量
[root@web-01 /server/scripts]# echo ${array[*]:1:3}  從下表爲1的元素截取3個元素
2 3 4
替換 和sed命令,和變量子字符串的替換 很像,是同樣的
[root@web-01 /server/scripts]# echo ${array[*]/1/999}
999 2 3 4 5 6 7 8 9 9990
[root@web-01 /server/scripts]# echo ${array[*]}  該操做不會改變原數組,要改變請參考賦值修改
1 2 3 4 5 6 7 8 9 10

數組也是變量,所以也適合於前面講解過的變量的子串處理的功能應用。
數組的其餘相關知識經過man bash而後搜Arrays來了解。

數組元素部份內容的刪除以下:
[root@oldboy data]# array=(one two three four five)
[root@oldboy data]# echo ${array[@]}               
one two three four five
[root@oldboy data]# echo ${array[@]#o*}    #<==從左邊開始匹配最短的,並刪除。
ne two three four five
[root@oldboy data]# echo ${array1[@]##o*}  #<==從左邊開始匹配最長的,並刪除。
two three four five
[root@oldboy data]# echo ${array[@]%f*}    #<==從右邊開始匹配最短的,並刪除。
one two three
[root@oldboy data]# echo ${array[@]%%f*}   #<==從右邊開始匹配最長的,並刪除。
one two three

使用for循環打印數組元素
array=(1 2 3 4 5)
for n in ${array[*]}
do
    echo $n
done
echo =====================
#i爲數組下標
for ((i=0;i<${#array[*]};i++))
do
    echo ${array[i]}
done 

array=([1]=one [2]=two [3]=three) 
array[0]=a;array[1]=b;array[2]=c
array=($(命令))
或
array=(`命令`)

 

shell數組企業面試題

一、利用bash for循環打印下面這句話中字母數不大於6的單詞(某企業面試真題)。

I am pizza teacher welcome to luffy training class

array=(I am oldboy teacher welcome to oldboy training class)

for word in ${array[*]}
#或者
#for ((i=0;i<=${
array[*];i++})) do if [ ${#word} -lt 6 ]
  # if [ ${#array[i]} -lt 6 ]
then echo $word
   # echo
array[i] fi done

 

    

 

第十四章 編程規範
第十五章 腳本調試
第十六章 vim配置
第十七章 trap
第十八章 expect
第十九章 企業案例實戰

第十九章 
企業面試題1:
分析:
1、獲取隨機小寫字符。
echo $RANDOM$(date +%N)|md5sum|tr "[0-9]" "a-z"|cut -c 2-11

2、for循環

企業面試題3:
101..10
[root@db03 ~]# seq -w 10
01
02
03
04
05
06
07
08
09
10
[root@db03 ~]# echo ${01..10}
-bash: ${01..10}: bad substitution
[root@db03 ~]# echo {01..10}
01 02 03 04 05 06 07 08 09 10

2echo $RANDOM|md5sum|cut 1-8
3、for循環批量設置用戶和密碼。

企業面試題4:

1、如何判斷機器是不是活的。
ping 10.0.0.53 -c 2 -W 3 有返回。
nmap -sP 10.0.0.0/24

2.for循環

#!/bin/sh
CMD="nmap -sP"
Ip="10.0.0.0/24"
$CMD $Ip|awk '/Nmap scan report for/ {print $NF}'

http://blog.51cto.com/oldboy/1632876
10,11,18,19,2013,6
相關文章
相關標籤/搜索