23 個非常實用的 Shell 拿來就用腳本實例

shell 腳本是幫助程序員和系統管理員完成費時費力的枯燥工作的利器,是與計算機交互並管理文件和系統操作的有效方式。區區幾行代碼,就可以讓計算機接近按照你的意圖行事。

爲大家整理了 23 個實例,通過 23 個實戰經典腳本實例,展示了 shell 腳本編程的實用技術和常見工具用法。大家只需根據自己的需求,將文中這些常見任務和可移植自動化腳本推廣應用到其他類似問題上,能解決那些三天兩頭碰上的麻煩事。

檢測兩臺服務器指定目錄下的文件一致性

 1#!/bin/bash
 2#####################################
 3#檢測兩臺服務器指定目錄下的文件一致性
 4#####################################
 5#通過對比兩臺服務器上文件的md5值,達到檢測一致性的目的
 6dir=/data/web
 7b_ip=192.168.88.10
 8#將指定目錄下的文件全部遍歷出來並作爲md5sum命令的參數,進而得到所有文件的md5值,並寫入到指定文件中
 9find $dir -type f|xargs md5sum > /tmp/md5_a.txt
10ssh $b_ip "find $dir -type f|xargs md5sum > /tmp/md5_b.txt"
11scp $b_ip:/tmp/md5_b.txt /tmp
12#將文件名作爲遍歷對象進行一一比對
13for f in `awk '{print 2} /tmp/md5_a.txt'`
14do
15#以a機器爲標準,當b機器不存在遍歷對象中的文件時直接輸出不存在的結果
16if grep -qw "$f" /tmp/md5_b.txt
17then
18md5_a=`grep -w "$f" /tmp/md5_a.txt|awk '{print 1}'`
19md5_b=`grep -w "$f" /tmp/md5_b.txt|awk '{print 1}'`
20#當文件存在時,如果md5值不一致則輸出文件改變的結果
21if [ $md5_a != $md5_b ]
22then
23echo "$f changed."
24fi
25else
26echo "$f deleted."
27fi
28done
29
30

定時清空文件內容,定時記錄文件大小

 1#!/bin/bash
 2################################################################
 3#每小時執行一次腳本(任務計劃),當時間爲0點或12點時,將目標目錄下的所有文件內
 4#容清空,但不刪除文件,其他時間則只統計各個文件的大小,一個文件一行,輸出到以時#間和日期命名的文件中,需要考慮目標目錄下二級、三級等子目錄的文件
 5################################################################
 6logfile=/tmp/`date +%H-%F`.log
 7n=`date +%H`
 8if [ $n -eq 00 ] || [ $n -eq 12 ]
 9then
10#通過for循環,以find命令作爲遍歷條件,將目標目錄下的所有文件進行遍歷並做相應操作
11for i in `find /data/log/ -type f`
12do
13true > $i
14done
15else
16for i in `find /data/log/ -type f`
17do
18du -sh $i >> $logfile
19done
20fi
21
22

檢測網卡流量,並按規定格式記錄在日誌中

 1#!/bin/bash
 2#######################################################
 3#檢測網卡流量,並按規定格式記錄在日誌中
 4#規定一分鐘記錄一次
 5#日誌格式如下所示:
 6#2019-08-12 20:40
 7#ens33 input: 1234bps
 8#ens33 output: 1235bps
 9######################################################3
10while :
11do
12#設置語言爲英文,保障輸出結果是英文,否則會出現bug
13LANG=en
14logfile=/tmp/`date +%d`.log
15#將下面執行的命令結果輸出重定向到logfile日誌中
16exec >> $logfile
17date +"%F %H:%M"
18#sar命令統計的流量單位爲kb/s,日誌格式爲bps,因此要*1000*8
19sar -n DEV 1 59|grep Average|grep ens33|awk '{print $2,"\t","input:","\t",$5*1000*8,"bps","\n",$2,"\t","output:","\t",$6*1000*8,"bps"}'
20echo "####################"
21#因爲執行sar命令需要59秒,因此不需要sleep
22done
23
24

計算文檔每行出現的數字個數,並計算整個文檔的數字總數

 1#!/bin/bash
 2#########################################################
 3#計算文檔每行出現的數字個數,並計算整個文檔的數字總數
 4########################################################
 5#使用awk只輸出文檔行數(截取第一段)
 6n=`wc -l a.txt|awk '{print $1}'`
 7sum=0
 8#文檔中每一行可能存在空格,因此不能直接用文檔內容進行遍歷
 9for i in `seq 1 $n`
10do
11#輸出的行用變量表示時,需要用雙引號
12line=`sed -n "$i"p a.txt`
13#wc -L選項,統計最長行的長度
14n_n=`echo $line|sed s'/[^0-9]//'g|wc -L`
15echo $n_n
16sum=$[$sum+$n_n]
17done
18echo "sum:$sum"
19
20

殺死所有腳本

1#!/bin/bash
2################################################################
3#有一些腳本加入到了cron之中,存在腳本尚未運行完畢又有新任務需要執行的情況,
4#導致系統負載升高,因此可通過編寫腳本,篩選出影響負載的進程一次性全部殺死。
5################################################################
6ps aux|grep 指定進程名|grep -v grep|awk '{print $2}'|xargs kill -9
7
8

從 FTP 服務器下載文件

 1#!/bin/bash
 2if [ $# -ne 1 ]; then
 3    echo "Usage: $0 filename"
 4fi
 5dir=$(dirname $1)
 6file=$(basename $1)
 7ftp -n -v << EOF   # -n 自動登錄
 8open 192.168.1.10  # ftp服務器
 9user admin password
10binary   # 設置ftp傳輸模式爲二進制,避免MD5值不同或.tar.gz壓縮包格式錯誤
11cd $dir
12get "$file"
13EOF
14
15

連續輸入 5 個 100 以內的數字,統計和、最小和最大

 1#!/bin/bash
 2COUNT=1
 3SUM=0
 4MIN=0
 5MAX=100
 6while [ $COUNT -le 5 ]; do
 7    read -p "請輸入1-10個整數:" INT
 8    if [[ ! $INT =~ ^[0-9]+$ ]]; then
 9        echo "輸入必須是整數!"
10        exit 1
11    elif [[ $INT -gt 100 ]]; then
12        echo "輸入必須是100以內!"
13        exit 1
14    fi
15    SUM=$(($SUM+$INT))
16    [ $MIN -lt $INT ] && MIN=$INT
17    [ $MAX -gt $INT ] && MAX=$INT
18    let COUNT++
19done
20echo "SUM: $SUM"
21echo "MIN: $MIN"
22echo "MAX: $MAX"
23
24

用戶猜數字

1#!/bin/bash  # 腳本生成一個 100 以內的隨機數,提示用戶猜數字,根據用戶的輸入,提示用戶猜對了,# 猜小了或猜大了,直至用戶猜對腳本結束。# RANDOM 爲系統自帶的系統變量,值爲 0‐32767的隨機數# 使用取餘算法將隨機數變爲 1‐100 的隨機數num=$[RANDOM%100+1]echo "$num" # 使用 read 提示用戶猜數字# 使用 if 判斷用戶猜數字的大小關係:‐eq(等於),‐ne(不等於),‐gt(大於),‐ge(大於等於),# ‐lt(小於),‐le(小於等於)while :do     read -p "計算機生成了一個 1‐100 的隨機數,你猜: " cai    if [ $cai -eq $num ]    then        echo "恭喜,猜對了"           exit        elif [ $cai -gt $num ]        then            echo "Oops,猜大了"         else            echo "Oops,猜小了"     fidone
2
3

監測 Nginx 訪問日誌 502 情況,並做相應動作

假設服務器環境爲 lnmp,近期訪問經常出現 502 現象,且 502 錯誤在重啓 php-fpm 服務後消失,因此需要編寫監控腳本,一旦出現 502,則自動重啓 php-fpm 服務。

 1#場景:
 2#1.訪問日誌文件的路徑:/data/log/access.log
 3#2.腳本死循環,每10秒檢測一次,10秒的日誌條數爲300條,出現502的比例不低於10%(30條)則需要重啓php-fpm服務
 4#3.重啓命令爲:/etc/init.d/php-fpm restart
 5#!/bin/bash
 6###########################################################
 7#監測Nginx訪問日誌502情況,並做相應動作
 8###########################################################
 9log=/data/log/access.log
10N=30 #設定閾值
11while :
12do
13 #查看訪問日誌的最新300條,並統計502的次數
14    err=`tail -n 300 $log |grep -c '502" '`
15 if [ $err -ge $N ]
16 then
17 /etc/init.d/php-fpm restart 2> /dev/null
18 #設定60s延遲防止腳本bug導致無限重啓php-fpm服務
19     sleep 60
20 fi
21 sleep 10
22done
23
24

將結果分別賦值給變量

 1應用場景:希望將執行結果或者位置參數賦值給變量,以便後續使用。
 2
 3方法1:
 4
 5for i in $(echo "4 5 6"); do
 6   eval a$i=$i
 7done
 8echo $a4 $a5 $a6
 9方法2:將位置參數192.168.1.1{1,2}拆分爲到每個變量
10
11num=0
12for i in $(eval echo $*);do   #eval將{1,2}分解爲1 2
13   let num+=1
14   eval node${num}="$i"
15done
16echo $node1 $node2 $node3
17# bash a.sh 192.168.1.1{1,2}
18192.168.1.11 192.168.1.12
19方法3:
20
21arr=(4 5 6)
22INDEX1=$(echo ${arr[0]})
23INDEX2=$(echo ${arr[1]})
24INDEX3=$(echo ${arr[2]})
25
26

批量修改文件名

 1示例:
 2
 3# touch article_{1..3}.html
 4# ls
 5article_1.html  article_2.html  article_3.html
 6目的:把article改爲bbs
 7
 8方法1:
 9
10for file in $(ls *html); do
11    mv $file bbs_${file#*_}
12    # mv $file $(echo $file |sed -r 's/.*(_.*)/bbs\1/')
13    # mv $file $(echo $file |echo bbs_$(cut -d_ -f2)
14done
15方法2:
16
17for file in $(find . -maxdepth 1 -name "*html"); do
18     mv $file bbs_${file#*_}
19done
20方法3:
21
22# rename article bbs *.html
23
24

把一個文檔前五行中包含字母的行刪掉,同時刪除 6 到 10 行包含的所有字母

1)準備測試文件,文件名爲 2.txt

 1第1行1234567不包含字母
 2第2行56789BBBBBB
 3第3行67890CCCCCCCC
 4第4行78asdfDDDDDDDDD
 5第5行123456EEEEEEEE
 6第6行1234567ASDF
 7第7行56789ASDF
 8第8行67890ASDF
 9第9行78asdfADSF
10第10行123456AAAA
11第11行67890ASDF
12第12行78asdfADSF
13第13行123456AAAA
14
15

2)腳本如下:

 1#!/bin/bash
 2##############################################################
 3#把一個文檔前五行中包含字母的行刪掉,同時刪除6到10行包含的所有字母
 4##############################################################
 5sed -n '1,5'p 2.txt |sed '/[a-zA-Z]/'d
 6sed -n '6,10'p 2.txt |sed s'/[a-zA-Z]//'g
 7sed -n '11,$'p 2.txt
 8#最終結果只是在屏幕上打印結果,如果想直接更改文件,可將輸出結果寫入臨時文件中,再替換2.txt或者使用-i選項
 9
10

統計當前目錄中以. html 結尾的文件總大

 1方法1:
 2
 3# find . -name "*.html" -exec du -k {} \; |awk '{sum+=$1}END{print sum}'
 4
 5方法2:
 6
 7for size in $(ls -l *.html |awk '{print $5}'); do
 8    sum=$(($sum+$size))
 9done
10echo $sum
11
12

掃描主機端口狀態

 1#!/bin/bash
 2HOST=$1
 3PORT="22 25 80 8080"
 4for PORT in $PORT; do
 5    if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then
 6        echo "$PORT open"
 7    else
 8        echo "$PORT close"
 9    fi
10done
11
12

用 shell 打印示例語句中字母數小於 6 的單詞

 1#示例語句:
 2#Bash also interprets a number of multi-character options.
 3#!/bin/bash
 4##############################################################
 5#shell打印示例語句中字母數小於6的單詞
 6##############################################################
 7for s in Bash also interprets a number of multi-character options.
 8do
 9 n=`echo $s|wc -c`
10 if [ $n -lt 6 ]
11 then
12 echo $s
13 fi
14done
15
16

輸入數字運行相應命令

 1#!/bin/bash
 2##############################################################
 3#輸入數字運行相應命令
 4##############################################################
 5echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit "
 6while :
 7do
 8#捕獲用戶鍵入值
 9 read -p "please input number :" n
10 n1=`echo $n|sed s'/[0-9]//'g`
11#空輸入檢測 
12 if [ -z "$n" ]
13 then
14 continue
15 fi
16#非數字輸入檢測 
17 if [ -n "$n1" ]
18 then
19 exit 0
20 fi
21 break
22done
23case $n in
24 1)
25 date
26 ;;
27 2)
28 ls
29 ;;
30 3)
31 who
32 ;;
33 4)
34 pwd
35 ;;
36 0)
37 break
38 ;;
39    #輸入數字非1-4的提示
40 *)
41 echo "please input number is [1-4]"
42esac
43
44

Expect 實現 SSH 免交互執行命令

 1Expect是一個自動交互式應用程序的工具,如telnet,ftp,passwd等。
 2
 3需先安裝expect軟件包。
 4
 5方法1:EOF標準輸出作爲expect標準輸入
 6
 7#!/bin/bash
 8USER=root
 9PASS=123.com
10IP=192.168.1.120
11expect << EOF
12set timeout 30
13spawn ssh $USER@$IP   
14expect {
15    "(yes/no)" {send "yes\r"; exp_continue}
16    "password:" {send "$PASS\r"}
17}
18expect "$USER@*"  {send "$1\r"}
19expect "$USER@*"  {send "exit\r"}
20expect eof
21EOF
22方法2:
23
24#!/bin/bash
25USER=root
26PASS=123.com
27IP=192.168.1.120
28expect -c "
29    spawn ssh $USER@$IP
30    expect {
31        \"(yes/no)\" {send \"yes\r\"; exp_continue}
32        \"password:\" {send \"$PASS\r\"; exp_continue}
33        \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue}
34    }"
35方法3:將expect腳本獨立出來
36
37登錄腳本:
38
39# cat login.exp
40#!/usr/bin/expect
41set ip [lindex $argv 0]
42set user [lindex $argv 1]
43set passwd [lindex $argv 2]
44set cmd [lindex $argv 3]
45if { $argc != 4 } {
46puts "Usage: expect login.exp ip user passwd"
47exit 1
48}
49set timeout 30
50spawn ssh $user@$ip
51expect {
52    "(yes/no)" {send "yes\r"; exp_continue}
53    "password:" {send "$passwd\r"}
54}
55expect "$user@*"  {send "$cmd\r"}
56expect "$user@*"  {send "exit\r"}
57expect eof
58執行命令腳本:寫個循環可以批量操作多臺服務器
59
60#!/bin/bash
61HOST_INFO=user_info.txt
62for ip in $(awk '{print $1}' $HOST_INFO)
63do
64    user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)
65    pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)
66    expect login.exp $ip $user $pass $1
67done
68Linux主機SSH連接信息:
69
70# cat user_info.txt
71192.168.1.120 root 123456
72
73

創建 10 個用戶,並分別設置密碼,密碼要求 10 位且包含大小寫字母以及數字,最後需要把每個用戶的密碼存在指定文件中

 1#!/bin/bash
 2##############################################################
 3#創建10個用戶,並分別設置密碼,密碼要求10位且包含大小寫字母以及數字
 4#最後需要把每個用戶的密碼存在指定文件中
 5#前提條件:安裝mkpasswd命令
 6##############################################################
 7#生成10個用戶的序列(00-09)
 8for u in `seq -w 0 09`
 9do
10 #創建用戶
11 useradd user_$u
12 #生成密碼
13 p=`mkpasswd -s 0 -l 10`
14 #從標準輸入中讀取密碼進行修改(不安全)
15 echo $p|passwd --stdin user_$u
16 #常規修改密碼
17 echo -e "$p\n$p"|passwd user_$u
18 #將創建的用戶及對應的密碼記錄到日誌文件中
19 echo "user_$u $p" >> /tmp/userpassword
20done
21
22

監控 httpd 的進程數,根據監控情況做相應處理

 1#!/bin/bash
 2###############################################################################################################################
 3#需求:
 4#1.每隔10s監控httpd的進程數,若進程數大於等於500,則自動重啓Apache服務,並檢測服務是否重啓成功
 5#2.若未成功則需要再次啓動,若重啓5次依舊沒有成功,則向管理員發送告警郵件,並退出檢測
 6#3.如果啓動成功,則等待1分鐘後再次檢測httpd進程數,若進程數正常,則恢復正常檢測(10s一次),否則放棄重啓並向管理員發送告警郵件,並退出檢測
 7###############################################################################################################################
 8#計數器函數
 9check_service()
10{
11 j=0
12 for i in `seq 1 5` 
13 do
14 #重啓Apache的命令
15 /usr/local/apache2/bin/apachectl restart 2> /var/log/httpderr.log
16    #判斷服務是否重啓成功
17 if [ $? -eq 0 ]
18 then
19 break
20 else
21 j=$[$j+1]
22 fi
23    #判斷服務是否已嘗試重啓5次
24 if [ $j -eq 5 ]
25 then
26 mail.py
27 exit
28 fi
29 done 
30}
31while :
32do
33 n=`pgrep -l httpd|wc -l`
34 #判斷httpd服務進程數是否超過500
35 if [ $n -gt 500 ]
36 then
37 /usr/local/apache2/bin/apachectl restart
38 if [ $? -ne 0 ]
39 then
40 check_service
41 else
42 sleep 60
43 n2=`pgrep -l httpd|wc -l`
44 #判斷重啓後是否依舊超過500
45             if [ $n2 -gt 500 ]
46 then 
47 mail.py
48 exit
49 fi
50 fi
51 fi
52 #每隔10s檢測一次
53 sleep 10
54done
55
56

批量修改服務器用戶密碼

 1Linux主機SSH連接信息:舊密碼
 2
 3# cat old_pass.txt 
 4192.168.18.217  root    123456     22
 5192.168.18.218  root    123456     22
 6內容格式:IP User Password Port
 7
 8SSH遠程修改密碼腳本:新密碼隨機生成
 9https://www.linuxprobe.com/books
10#!/bin/bash
11OLD_INFO=old_pass.txt
12NEW_INFO=new_pass.txt
13for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do
14    USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO)
15    PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO)
16    PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO)
17    NEW_PASS=$(mkpasswd -l 8)  # 隨機密碼
18    echo "$IP   $USER   $NEW_PASS   $PORT" >> $NEW_INFO
19    expect -c "
20    spawn ssh -p$PORT $USER@$IP
21    set timeout 2
22    expect {
23        \"(yes/no)\" {send \"yes\r\";exp_continue}
24        \"password:\" {send \"$PASS\r\";exp_continue}
25        \"$USER@*\" {send \"echo \'$NEW_PASS\' |passwd --stdin $USER\r exit\r\";exp_continue}
26    }"
27done
28生成新密碼文件:
29
30# cat new_pass.txt 
31192.168.18.217  root    n8wX3mU%      22
32192.168.18.218  root    c87;ZnnL      22
33
34

iptables 自動屏蔽訪問網站頻繁的 IP

 1場景:惡意訪問,安全防範
 2
 31)屏蔽每分鐘訪問超過200的IP
 4
 5方法1:根據訪問日誌(Nginx爲例)
 6
 7#!/bin/bash
 8DATE=$(date +%d/%b/%Y:%H:%M)
 9ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}')
10#先tail防止文件過大,讀取慢,數字可調整每分鐘最大的訪問量。awk不能直接過濾日誌,因爲包含特殊字符。
11for IP in $ABNORMAL_IP; do
12    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
13        iptables -I INPUT -s $IP -j DROP
14    fi
15done
16方法2:通過TCP建立的連接
17
18#!/bin/bash
19ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}')
20#gsub是將第五列(客戶端IP)的冒號和端口去掉
21for IP in $ABNORMAL_IP; do
22    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
23        iptables -I INPUT -s $IP -j DROP
24    fi
25done
26
272)屏蔽每分鐘SSH嘗試登錄超過10次的IP
28
29方法1:通過lastb獲取登錄狀態:
30
31#!/bin/bash
32DATE=$(date +"%a %b %e %H:%M") #星期月天時分  %e單數字時顯示7,而%d顯示07
33ABNORMAL_IP=$(lastb |grep "$DATE" |awk '{a[$3]++}END{for(i in a)if(a[i]>10)print i}')
34for IP in $ABNORMAL_IP; do
35    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
36        iptables -I INPUT -s $IP -j DROP
37    fi
38done
39方法2:通過日誌獲取登錄狀態
40
41#!/bin/bash
42DATE=$(date +"%b %d %H")
43ABNORMAL_IP="$(tail -n10000 /var/log/auth.log |grep "$DATE" |awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}')"
44for IP in $ABNORMAL_IP; do
45    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
46        iptables -A INPUT -s $IP -j DROP
47        echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >>~/ssh-login-limit.log
48    fi
49done
50
51

根據 web 訪問日誌,封禁請求量異常的 IP,如 IP 在半小時後恢復正常,則解除封禁

 1#!/bin/bash
 2####################################################################################
 3#根據web訪問日誌,封禁請求量異常的IP,如IP在半小時後恢復正常,則解除封禁
 4####################################################################################
 5logfile=/data/log/access.log
 6#顯示一分鐘前的小時和分鐘
 7d1=`date -d "-1 minute" +%H%M`
 8d2=`date +%M`
 9ipt=/sbin/iptables
10ips=/tmp/ips.txt
11block()
12{
13 #將一分鐘前的日誌全部過濾出來並提取IP以及統計訪問次數
14 grep '$d1:' $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n > $ips
15 #利用for循環將次數超過100的IP依次遍歷出來並予以封禁
16 for i in `awk '$1>100 {print $2}' $ips`
17 do
18 $ipt -I INPUT -p tcp --dport 80 -s $i -j REJECT
19 echo "`date +%F-%T` $i" >> /tmp/badip.log
20 done
21}
22unblock()
23{
24 #將封禁後所產生的pkts數量小於10的IP依次遍歷予以解封
25 for a in `$ipt -nvL INPUT --line-numbers |grep '0.0.0.0/0'|awk '$2<10 {print $1}'|sort -nr`
26 do 
27 $ipt -D INPUT $a
28 done
29 $ipt -Z
30}
31#當時間在00分以及30分時執行解封函數
32if [ $d2 -eq "00" ] || [ $d2 -eq "30" ]
33 then
34 #要先解再封,因爲剛剛封禁時產生的pkts數量很少
35 unblock
36 block
37 else
38 block
39fi
40
41

判斷用戶輸入的是否爲 IP 地址

 1方法1:
 2
 3#!/bin/bash
 4function check_ip(){
 5    IP=$1
 6    VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
 7    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
 8        if [ $VALID_CHECK == "yes" ]; then
 9            echo "$IP available."
10        else
11            echo "$IP not available!"
12        fi
13    else
14        echo "Format error!"
15    fi
16}
17check_ip 192.168.1.1
18check_ip 256.1.1.1
19方法2:
20
21#!/bin/bash
22function check_ip(){
23    IP=$1
24    if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}]]; then
25        FIELD1=$(echo $IP|cut -d. -f1)
26        FIELD2=$(echo $IP|cut -d. -f2)
27        FIELD3=$(echo $IP|cut -d. -f3)
28        FIELD4=$(echo $IP|cut -d. -f4)
29        if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then
30            echo "$IP available."
31        else
32            echo "$IP not available!"
33        fi
34    else
35        echo "Format error!"
36    fi
37}
38check_ip 192.168.1.1
39check_ip 256.1.1.1
40增加版:
41
42加個死循環,如果IP可用就退出,不可用提示繼續輸入,並使用awk判斷。
43
44#!/bin/bash
45function check_ip(){
46    local IP=$1
47    VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
48    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
49        if [ $VALID_CHECK == "yes" ]; then
50            return 0
51        else
52            echo "$IP not available!"
53            return 1
54        fi
55    else
56        echo "Format error! Please input again."
57        return 1
58    fi
59}
60while true; do
61    read -p "Please enter IP: " IP
62    check_ip $IP
63    [ $? -eq 0 ] && break || continue
64done
65
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s?__biz=MzAwMjg1NjY3Nw==&amp;mid=2247508327&amp;idx=1&amp;sn=aaa9f629383de4f9c7bdf3a1b9e1b9a7&amp;chksm=9ac6e2edadb16bfb8cebcea7f0bbf220800c200f2c33b6a9844accd0d5ecbf4364c55ce51364&amp;scene=132#wechat_redirect