最近使用了個自動化平臺(詳見自動化運維平臺Spug測試)進行每週的變動,效果很不錯,平臺將大量重複繁瑣的操做經過腳本分發方式標準化自動化了,平臺核心是下發到各個服務器的shell腳本,感受有必要對shell腳本作個總結,因此有了寫本專題的想法。本專題將結合運維實際介紹shell腳本的各項用法,預計10篇左右,將包括系統巡檢、監控、ftp上傳下載、數據庫查詢、日誌清理、時鐘同步、定時任務等,裏面會涉及shell經常使用語法、注意事項、調試排錯等。html
本文是該專題的第五篇。git
文章主要介紹如何在腳本執行時傳參、如何對傳入的參數作基本的處理、如何處理選項、怎樣執行用戶輸出。github
主機名 | 操做系統版本 | ip | 備註 |
---|---|---|---|
shell | Centos 7.6.1810 | 172.16.7.100 | shell測試服務器 |
[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
傳入的參數能夠是數字、字符和字符串docker
\$0 是腳本名, \$1是第一個參數, \$2 是第二個參數,依次類推,直到第九個參數 $9shell
[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
只有傳入的參數個數爲5時腳本才能正常運行,避免由於參數個數傳入有誤形成腳本執行報錯。bash
[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
\$和\$@均可以獲取到左右的傳入參數,區別是 \$\變量會將全部參數當成單個參數,而 \$@變量會單獨處理每一個參數。服務器
使用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
使用while先判斷輸入的參數1是否存在,若是非空則執行下面的操做:先輸出參數$1,而後使用shift將參數\$2移動爲新的\$1,如此循環,直至全部參數被遍歷。ide
[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
case 語句會檢查每一個參數是否是有效選項。若是是的話,就運行對應 case 語句中的命令。
當參數爲start、stop、restart和status時執行對應的命令,若爲其它參數則提醒需輸入正確命令並退出。
使用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 中斷執行
-p 選項能夠指定提示符「是否繼續 Enter[Y/N]?」,-n 選項和值 1 一塊兒使用,告訴 read 命令在接受單個字符後退出。
[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!
-s 選項能夠避免在 read 命令中輸入的數據出如今顯示器上(實際上,數據會被顯示,只是read 命令會將文本顏色設成跟背景色同樣)
-t 選項來指定一個計時器,即5秒鐘後沒輸入退出程序。
[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
本例使用 read 命令來讀取文件數據,對文件使用 cat 命令,將結果經過管道直接傳給含有 read 的 while 命令,也可使用輸出重定向方式,參見shell腳本專題(04):循環中的「2.批量新增用戶」
參數傳入是腳本執行時的一個重要的方式,可讓腳本的執行更加靈活方便,交互的界面使腳本執行更具可讀性。本文介紹了三種交互方式:命令行參數、選項和read方式。掌握了這三種方式會讓腳本更優雅功能性更強。
本文全部腳本和安裝包文件已上傳github:shell-scripts-05
更多請點擊:shell專題