shell腳本專題(05):傳參

1、專題背景

最近使用了個自動化平臺(詳見自動化運維平臺Spug測試)進行每週的變動,效果很不錯,平臺將大量重複繁瑣的操做經過腳本分發方式標準化自動化了,平臺核心是下發到各個服務器的shell腳本,感受有必要對shell腳本作個總結,因此有了寫本專題的想法。本專題將結合運維實際介紹shell腳本的各項用法,預計10篇左右,將包括系統巡檢、監控、ftp上傳下載、數據庫查詢、日誌清理、時鐘同步、定時任務等,裏面會涉及shell經常使用語法、注意事項、調試排錯等。html

2、本文前言

本文是該專題的第五篇。git

文章主要介紹如何在腳本執行時傳參、如何對傳入的參數作基本的處理、如何處理選項、怎樣執行用戶輸出。github

3、環境說明

主機名 操做系統版本 ip 備註
shell Centos 7.6.1810 172.16.7.100 shell測試服務器

4、腳本測試

1.命令行參數

[root@shell param]# more test1.sh 
#!/bin/bash

name=$(basename $0)
total=$[ $4 * $5 ]

echo 這是第一個參數: $1
echo 這是第二個參數: $2
echo 這是第三個參數: $3
echo 這是第四個參數: $4
echo 這是第五個參數: $5

echo 腳本名稱爲 $name
echo $4乘以$5的值爲 $total

[root@shell param]# ./test1.sh 1 a "b c" 4 5
這是第一個參數: 1
這是第二個參數: a
這是第三個參數: b c
這是第四個參數: 4
這是第五個參數: 5
腳本名稱爲 test1.sh
4乘以5的值爲 20

image-20210324151529584

傳入的參數能夠是數字、字符和字符串docker

\$0 是腳本名, \$1是第一個參數, \$2 是第二個參數,依次類推,直到第九個參數 $9shell

2.判斷參數個數

[root@shell param]# ./test1.sh 
./test1.sh:行4: *  : 語法錯誤: 期待操做數 (錯誤符號是 "*  ")
這是第一個參數:
這是第二個參數:
這是第三個參數:
這是第四個參數:
這是第五個參數:
腳本名稱爲 test1.sh
乘以的值爲

當腳本執行時未加參數則執行報錯,此時須要對腳本進行優化,可使用特殊變量$#判斷傳入腳本的參數個數。數據庫

[root@shell param]# more test1.sh 
#!/bin/bash

if [ $# -ne 5 ]
then
    echo 參數個數有誤,請從新輸入
else
    name=$(basename $0)
    total=$[ $4 * $5 ]
    echo 這是第一個參數: $1
    echo 這是第二個參數: $2
    echo 這是第三個參數: $3
    echo 這是第四個參數: $4
    echo 這是第五個參數: $5
    echo 腳本名稱爲 $name
    echo $4乘以$5的值爲 $total
fi
[root@shell param]# ./test1.sh 
參數個數有誤,請從新輸入
[root@shell param]# ./test1.sh  1 2 3 4
參數個數有誤,請從新輸入
[root@shell param]# ./test1.sh  1 2 3 
參數個數有誤,請從新輸入
[root@shell param]# ./test1.sh  1 2 3 4 5 6 
參數個數有誤,請從新輸入
[root@shell param]# ./test1.sh 1 a "b c" 4 5
這是第一個參數: 1
這是第二個參數: a
這是第三個參數: b c
這是第四個參數: 4
這是第五個參數: 5
腳本名稱爲 test1.sh
4乘以5的值爲 20

image-20210324152227970

只有傳入的參數個數爲5時腳本才能正常運行,避免由於參數個數傳入有誤形成腳本執行報錯。bash

3.獲取全部的參數

[root@shell param]# more test2.sh 
#!/bin/bash
i=1
for param in "$*"
do
echo "參數$i = $param"
i=$[ $i + 1 ]
done

j=1
for param in "$@"
do
echo "參數$j = $param"
j=$[ $j + 1 ]
done
[root@shell param]# ./test2.sh  a b c
參數1 = a b c
參數1 = a
參數2 = b
參數3 = c

image-20210324153824611

\$和\$@均可以獲取到左右的傳入參數,區別是 \$\變量會將全部參數當成單個參數,而 \$@變量會單獨處理每一個參數。服務器

4.遍歷參數

使用shift命令默認狀況下它會將每一個參數變量向左移動一個位置,可使用這個方法遍歷全部傳入的參數。運維

[root@shell param]# more test3.sh 
#!/bin/bash
i=1
while [ -n "$1" ]
do
  echo "參數$i = $1"
  i=$[ $i + 1 ]
  shift
done
[root@shell param]# ./test3.sh  a b c
參數1 = a
參數2 = b
參數3 = c

image-20210324162018725

使用while先判斷輸入的參數1是否存在,若是非空則執行下面的操做:先輸出參數$1,而後使用shift將參數\$2移動爲新的\$1,如此循環,直至全部參數被遍歷。ide

5.選項處理

[root@shell param]# more test4.sh
#!/bin/bash

name=$(basename $0)

case $1  in
'start')
        systemctl start docker
        ;;
'stop')
        systemctl stop docker
        ;;
'restart')
        systemctl restart docker
        ;;
'status')
        systemctl status docker
        ;;
*)    
        echo "Usage: sh $name {start|stop|restart|status}"
        exit 3
esac
[root@shell param]# ./test4.sh
Usage: sh test4.sh {start|stop|restart|status}
[root@shell param]# ./test4.sh abc
Usage: sh test4.sh {start|stop|restart|status}
[root@shell param]# ./test4.sh stop
[root@shell param]# ./test4.sh start
[root@shell param]# ./test4.sh status

image-20210325095340188

case 語句會檢查每一個參數是否是有效選項。若是是的話,就運行對應 case 語句中的命令。

當參數爲start、stop、restart和status時執行對應的命令,若爲其它參數則提醒需輸入正確命令並退出。

6.用戶輸入

6.1基本讀取

使用read能夠從標準輸入(鍵盤)或另外一個文件描述符中接受輸入,在收到輸入後, read 命令會將數據放進一個變量。

[root@shell param]# more test5.sh 
#!/bin/bash
read  -n1 -p  "是否繼續 Enter[Y/N]? " option

case $option in
Y | y) echo
echo "繼續執行下一步: Hello World!";;
N | n) echo
echo "中斷執行"
exit;;
esac
[root@shell param]# ./test5.sh 
是否繼續 Enter[Y/N]? y
繼續執行下一步: Hello World!
[root@shell param]# ./test5.sh 
是否繼續 Enter[Y/N]? N
中斷執行

image-20210325164922501

-p 選項能夠指定提示符「是否繼續 Enter[Y/N]?」,-n 選項和值 1 一塊兒使用,告訴 read 命令在接受單個字符後退出。

6.2隱藏讀取

[root@shell param]# more test6.sh 
#!/bin/bash
read -t 5 -s -p "Enter your password: " pass
echo
echo "顯示輸入的密碼: $pass "
[root@shell param]# ./test6.sh 
Enter your password: 
顯示輸入的密碼: abc123!

image-20210325171358253

-s 選項能夠避免在 read 命令中輸入的數據出如今顯示器上(實際上,數據會被顯示,只是read 命令會將文本顏色設成跟背景色同樣)

-t 選項來指定一個計時器,即5秒鐘後沒輸入退出程序。

6.3文件讀取

[root@shell param]# more test7.sh 
#!/bin/bash
i=1
cat myfile | while read myline
do
echo "第$i行: $myline"
i=$[ $i + 1]
done
[root@shell param]# more myfile 
abc123!
123abc!
!123abc
abc!123
123!abc
!abc123
[root@shell param]# ./test7.sh 
第1行: abc123!
第2行: 123abc!
第3行: !123abc
第4行: abc!123
第5行: 123!abc
第6行: !abc123

image-20210325172041797

本例使用 read 命令來讀取文件數據,對文件使用 cat 命令,將結果經過管道直接傳給含有 read 的 while 命令,也可使用輸出重定向方式,參見shell腳本專題(04):循環中的「2.批量新增用戶」

5、本文總結

參數傳入是腳本執行時的一個重要的方式,可讓腳本的執行更加靈活方便,交互的界面使腳本執行更具可讀性。本文介紹了三種交互方式:命令行參數、選項和read方式。掌握了這三種方式會讓腳本更優雅功能性更強。

 

 

本文全部腳本和安裝包文件已上傳github:shell-scripts-05

更多請點擊:shell專題

相關文章
相關標籤/搜索