第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Shell 流程控制

1. 流程控制概述

1.1 流程控制簡介

Shell 腳本默認從上到下順序執(zhí)行,在程序運行中,會遇到很多種情況,對應不同情況執(zhí)行對應的操作,例如對于一批數據需要進行執(zhí)行重復工作,這些都需要我們使用特定的流程控制語句來實現,我們想要程序完成預定的操作,就需要熟練掌握流程控制語句,不同的流程控制語句有不同的適應場景。

1.2 為什么要用流程控制

流程控制是每種編程語言控制邏輯走向和執(zhí)行次序的重要組成部分,流程控制可以說是一門語言的 “經脈”,其控制著程序的運行走向,所以熟練掌握流程控制語句才能更好的控制整個腳本的運行結果,來完成我們的需求。

2. Shell 流程控制操作

2.1 條件語句

顧名思義,就是滿足特定條件執(zhí)行對應操作,按照順序從上到下,條件語句 if 通常需要與 test 命令配合使用,當滿足條件則執(zhí)行 then 后的 command,否則繼續(xù)往下運行執(zhí)行對應的 command,條件語句 if 是 Shell 編程中最基礎的條件判斷流程語句。

2.1.1 單分支 if 語句

顧名思義就是只有一個 if 語句塊包含的語句,condition 為正確則執(zhí)行 then 內的命令,語法:

if condition
then
    command1 
    command2
    ...
    commandN 
fi

對于 sshd 進程是否存在,可以使用單分支 if 語句來判斷,例如:

if [ $(ps -ef |grep /usr/sbin/sshd|grep -v grep|wc -l) -eq 1 ];then 
	echo "sshd server exist"
fi

2.1.2 雙分支 if 語句

多分支 if 語句存在 else 情況,語法:

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

統(tǒng)一判斷 sshd 服務,可以在 else 中進行一些列操作,例如:

if [ $(ps -ef |grep /usr/sbin/sshd|grep -v grep|wc -l) -eq 1 ];then 
	echo "sshd server exist"
else
	service sshd start && echo "啟動sshd服務"
fi

2.1.3 多分支 if 語句

顧名思義有多個 if 條件,在此利用 elif 來表示,注意最后有一個 else 結尾。

if condition1;then
    command1
elif condition2;then 
    command2
    ...
...
elif conditionN,then
		commandN
else
    command
fi

我們的 linux 系統(tǒng)有多個版本,可以利用多分支 if 語句來進行判斷,例如:

#! /bin/bash

sys_version=$(rpm -q centos-release|cut -d- -f3)

if [ $sys_version -eq 6 ];then
	echo "sysversion is $sys_version"
elif [ $sys_version -eq 7 ];then
	echo "sysversion is $sys_version"
else
	echo "sysversion is ${sys_version}"
fi

2.2 循環(huán)語句

對于一批數據,我們需要對其重復進行操作的時候,就需要利用循環(huán)語句來操作。

2.2.1 for 循環(huán)

for 循環(huán)語句通常應用在可預估數量的一批對象操作中,默認 for 循環(huán)的取值列表是以 $IFS 分割,默認 $IFS 為空白符,如果我們有其他需求可以更改,語法為:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

通過 for 循環(huán)每次遍歷一個后面跟的對象,在 do…done 操作塊中對對象進行一些列操作。

例如我們來求和 1-10 的和:

SUM=0
for num in $(seq 1 10)
do
		let SUM=${SUM}+${num}
done
echo "1-10的和為:${SUM}"

當然在 for 循環(huán)語句里面也可以配合 if 條件判斷或其他流程控制語句進行操作。

在此我們舉例修改 $IFS 的應用場景,首選備份默認當前的 $IFS,之后為其賦值新的 $IFS:,在對 /etc/passwd 進行操作完成后,恢復之前的 $IFS, 在此我們就利用改變 $IFS 對 /etc/passwd 的單個字段進行了變量操作。

#!/bin/bash
OLD_IFS=$IFS
IFS=":"
for i in $(head -1 /etc/passwd); do
echo $i
done
IFS=${OLD_IFS}
[root@xuel-terraform-cvm-0 ~]# bash 1.sh
root
x
0
0
root
/root
/bin/bash
[root@xuel-terraform-cvm-0 ~]# cat /etc/passwd |head -1
root:x:0:0:root:/root:/bin/bash

for 循環(huán)如果條件永遠滿足則,一直執(zhí)行內部的命令。

for (( ; ; ))

2.2.2 while 循環(huán)

while 循環(huán)同樣為循環(huán),與 for 循環(huán)功能一樣,利用 for 循環(huán)的語句同樣也可以使用 while 循環(huán)完成,但是 while 循環(huán)通常用于處理未知數量對象的操作,語法:

while 條件表達式:do
    command
done

while 通常與 test 語句配合使用,如果條件表達式成立,則一直執(zhí)行。

例如求和打印 1-5 個數:

#!/bin/bash
N=0
while [ $N -lt 5 ]; do
  let N++
  echo $N
done

也可以利用 read 讀入文件,例如我們來讀入一個寫有 ip 或域名列表的文件,來判斷該文件內的域名或 IP 網絡是否可達。

#!/bin/bash
#function:check url
filename=urllist.txt
for url in $(cat $filename)
do
  status=`curl -I --connect-timeout 5 $url -s|awk '/HTTP/{print $2}'`
  if [[ $status == "200" ]];then
          echo "Url:$url is ok!   status is $status"
  else
          echo "Url:$url is error! status is $status"
  fi
done

編寫 urllist.txt

[root@xuel-terraform-cvm-0 ~]# cat urllist.txt
baidu.com
114.114.114.114
[root@xuel-terraform-cvm-0 ~]# bash urlcheck.sh
Url:baidu.com is ok!   status is 200
Url:114.114.114.114 is error! status is

如果 while 的判斷條件為永遠為 true,則稱為無限循環(huán),會一直執(zhí)行內部的操作,例如:

while :
do
    command
done

或者
while true
do
    command
done

2.2.3 until 循環(huán)

until 循環(huán)與 while 循環(huán)剛好相反,其也有一定的應用場景,其為條件表達式為 true 時停止,否則一直運行,語法:

until 條件表達式
do
    command
done

例如我們使用 until 來打印 1-5 數字:

NUM=0
until [ ${NUM} -ge 5 ]
do 
	let NUM++
	echo $NUM
done

2.2.4 break 與 continue

與上面三個循環(huán)語句不同的是,break 為跳出循環(huán),continue 則為不執(zhí)行下一次操作,直接跳到下一次循環(huán)。

我們可以利用 break 來跳出終止循環(huán)。

  • break
#!/bin/bash

N=0
while true; do
    let N++
    if [ $N -eq 5 ]; then
    break
    fi
    echo $N
done
  • continue
#!/bin/bash
N=0
while [ $N -lt 5 ]; do
    let N++
    if [ $N -eq 3 ]; then
        continue
    fi
    echo $N
done

利用 continue 來跳過特定的條件操作。

2.3 選擇語句

2.3.1 case 語句

選擇語句 case 可以在特定的幾個條件中選擇某一個進行執(zhí)行,其他 case 可以利用 if 多分支來替代。

case 模式名	in
    模式 1)
        命令
        ;;
    模式 2)
        命令
        ;;
    *)
        不符合以上模式執(zhí)行的命令
esac

例如我們服務的啟動操作腳本就是利用 case 語句來,當用戶的輸入與模式名相匹配則執(zhí)行對應的命令。

#!/bin/bash
case $1 in
    start)
        echo "start."   
        ;;
    stop)
        echo "stop."
        ;;
    restart)
        echo "restart."
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
esac

3. 實例

3.1 需求

編寫一個腳本,來對當前系統(tǒng) PATH 目錄下的二進制執(zhí)行文件進行,或者對指定全盤進行 md5 掃描,后期可以配合定時任務來監(jiān)控文件是否變化,用于文件權限及內容的管控。

3.2 思路

文件掃描可以使用 md5sum 工具執(zhí)行,對目錄遍歷需要使用 for 循環(huán),現在執(zhí)行方式可以使用 case 來操作,其中一些操作會涉及到 sed 的命令,后期我們會針對這些命令進行單獨章節(jié)詳細講解,在本需求案例中著重思考 Shell 中流程控制的作用。

3.3 實現

  • 具體實現 shell 腳本
#!/bin/bash
# Description: count file scripts
# Auth: kaliarch
# Email: kaliarch@163.com
# function: count file
# Date: 2020-03-28 14:00
# Version: 1.0

# 定義文件掃描目錄

SCAN_DIR=`echo $PATH |sed 's/:/ /g'`
SCAN_CMD=`which md5sum`
SCAN_FILE_FAIL="/tmp/scan_$(date +%F%H%m)_fall.txt"
SCAN_FILE_BIN="/tmp/scan_$(date +%F%H%m)_bin.txt"

scan_fall_disk() {
	echo "正在全盤掃描,請稍等!文件路徑:$SCAN_FILE_FALL"
	find / -type f ! -path "/proc/*" -exec $SCAN_CMD \{\} \;>> $SCAN_FILE_FAIL 2>/dev/null
	echo "掃描完成,可利用以下命令后期對文件進行校驗"
	echo "$SCAN_CMD -c $SCAN_FILE_FAIL |grep -v 'OK$'"
}

scan_bin() {
	echo "正在掃描$PATH可執(zhí)行文件,請稍等,文件路徑:$SCAN_FILE_BIN"
	for file in $SCAN_DIR
	do
		find $file -type f -exec $SCAN_CMD \{\} \;>> $SCAN_FILE_BIN 2>/dev/null
	done
	echo "掃描完成,可利用以下命令后期對文件進行校驗"
	echo "$SCAN_CMD -c $SCAN_FILE_BIN |grep -v 'OK$'"
}

clear
echo "##########################################"
echo "#                                        #"
echo "#        利用md5sum對文件進行校驗        #"
echo "#                                        #"
echo "##########################################"
echo "1: 全盤掃描"
echo "2: bin path掃描"
echo "3: EXIT"
# 選擇掃描方式
read -p "Please input your choice:" method
case $method in 
1)
	scan_fall_disk;;
2)
	scan_bin;;
3)
        echo "you choce channel!" && exit 1;;
*)
	echo "input Error! Place input{1|2|3}" && exit 0;;
esac
  • 測試
[root@xuel-terraform-cvm-0 ~]# bash file_scan.sh
##########################################
#                                        #
#        利用md5sum對文件進行校驗        #
#                                        #
##########################################
1: 全盤掃描
2: bin path掃描
3: EXIT
Please input your choice:2
正在掃描/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin可執(zhí)行文件,請稍等,文件路徑:/tmp/scan_2020-03-271703_bin.txt
掃描完成,可利用以下命令后期對文件進行校驗
/usr/bin/md5sum -c /tmp/scan_2020-03-271703_bin.txt |grep -v 'OK$'
[root@xuel-terraform-cvm-0 ~]# /usr/bin/md5sum -c /tmp/scan_2020-03-271703_bin.txt |grep -v 'OK$'
/sbin/mii-tool: 確定
/sbin/wipefs: 確定
/sbin/blkdiscard: 確定
/sbin/rtmon: 確定
/sbin/shutdown: 確定
/sbin/aureport: 確定
/sbin/plymouthd: 確定
/sbin/udevd: 確定
/sbin/lvmetad: 確定
/sbin/e2undo: 確定
...

當我們輸入數字 2 的時候即對 bin 路徑執(zhí)行掃描,掃描完成后會生成對應的掃描文件,可以執(zhí)行 /usr/bin/md5sum -c /tmp/scan_2020-03-271703_bin.txt |grep -v 'OK$' 來進行后期文件校驗。

[root@xuel-terraform-cvm-0 ~]# bash file_scan.sh
##########################################
#                                        #
#        利用md5sum對文件進行校驗           #
#                                        #
##########################################
1: 全盤掃描
2: bin path掃描
3: EXIT
Please input your choice:3
you choce channel!

當輸入 3 程序退出,在此就是使用 case 來完成。

[root@xuel-terraform-cvm-0 ~]# bash file_scan.sh
##########################################
#                                        #
#        利用md5sum對文件進行校驗        	 #
#                                        #
##########################################
1: 全盤掃描
2: bin path掃描
3: EXIT
Please input your choice:1
正在全盤掃描,請稍等!文件路徑:
掃描完成,可利用以下命令后期對文件進行校驗
/usr/bin/md5sum -c /tmp/scan_2020-03-271703_fall.txt |grep -v 'OK$'
[root@xuel-terraform-cvm-0 ~]# /usr/bin/md5sum -c /tmp/scan_2020-03-271703_fall.txt |grep -v 'OK$' |more
/sys/devices/platform/uevent: 確定
/sys/devices/platform/power/control: 確定
/sys/devices/platform/power/wakeup: 確定
/sys/devices/platform/pcspkr/uevent: 確定
/sys/devices/platform/pcspkr/modalias: 確定
/sys/devices/platform/pcspkr/power/control: 確定
/sys/devices/platform/pcspkr/power/wakeup: 確定
/sys/devices/platform/platform-framebuffer.0/uevent: 確定
/sys/devices/platform/platform-framebuffer.0/modalias: 確定
/sys/devices/platform/platform-framebuffer.0/power/control: 確定
/sys/devices/platform/platform-framebuffer.0/power/wakeup: 確定
/sys/devices/platform/serial8250/uevent: 確定
/sys/devices/platform/serial8250/modalias: 確定
/sys/devices/platform/serial8250/power/control: 確定
/sys/devices/platform/serial8250/power/wakeup: 確定
/sys/devices/platform/serial8250/tty/ttyS1/uevent: 確定
/sys/devices/platform/serial8250/tty/ttyS1/dev: 確定
/sys/devices/platform/serial8250/tty/ttyS1/power/cont

4. 注意事項

  • 對于條件語句中的多分支 if 語句,結尾肯定是有一個 else 來完成,需要注意此點;
  • 在編寫流程控制時候,可以根據自己的習慣對于 command 中的操作進行縮進,可以為幾個空格,也可以為一個 tab 鍵,建議使用一個制表符;
  • 流程控制語句可以相互嵌套,例如 for 循環(huán)中可以有 if 條件判斷,if 添加判斷中也可以添加 for 循環(huán)等,根據需求具體靈活運用;
  • case 語句與 if 多分支語句一樣,不同點在與 case 語句只能判斷一種條件關系,而 if 多分支可以對多種條件進行判斷。

5. 小結

流程控制語句是我們 Shell 編寫的經絡,利用它來控制程序的走向,需要我們能熟練掌握最常用的流程控制語句,并知道其對應的適應場景,靈活配合使用。