對(duì)于初學(xué)者而言,因?yàn)闆](méi)有實(shí)戰(zhàn)經(jīng)驗(yàn),寫(xiě)不出來(lái)Shell腳本很正常,如果工作了幾年的運(yùn)維老年還是寫(xiě)不出來(lái),那就是沒(méi)主動(dòng)找需求,缺乏練習(xí),缺乏經(jīng)驗(yàn)。針對(duì)以上問(wèn)題,總結(jié)了30個(gè)生產(chǎn)環(huán)境中經(jīng)典的Shell腳本,通過(guò)這些需求案例,希望能幫助大家提升Shell編寫(xiě)思路,掌握編寫(xiě)技巧。 |
先了解下編寫(xiě)Shell過(guò)程中注意事項(xiàng):
10年積累的成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先制作網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有太和免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。開(kāi)頭加解釋器:#!/bin/bash 語(yǔ)法縮進(jìn),使用四個(gè)空格;多加注釋說(shuō)明。 命名建議規(guī)則:變量名大寫(xiě)、局部變量小寫(xiě),函數(shù)名小寫(xiě),名字體現(xiàn)出實(shí)際作用。 默認(rèn)變量是全局的,在函數(shù)中變量local指定為局部變量,避免污染其他作用域。 有兩個(gè)命令能幫助我調(diào)試腳本:set?-e?遇到執(zhí)行非0時(shí)退出腳本,set-x?打印執(zhí)行過(guò)程。 寫(xiě)腳本一定先測(cè)試再到生產(chǎn)上。
1、獲取隨機(jī)字符串或數(shù)字
獲取隨機(jī)8位字符串: 方法1: #?echo?$RANDOM?|md5sum?|cut?-c?1-8 471b94f2 方法2: #?openssl?rand?-base64?4 vg3BEg== 方法3: #?cat?/proc/sys/kernel/random/uuid?|cut?-c?1-8 ed9e032c 獲取隨機(jī)8位數(shù)字: 方法1: #?echo?$RANDOM?|cksum?|cut?-c?1-8 23648321 方法2: #?openssl?rand?-base64?4?|cksum?|cut?-c?1-8 38571131 方法3: #?date?+%N?|cut?-c?1-8 69024815 cksum:打印CRC效驗(yàn)和統(tǒng)計(jì)字節(jié)
2、定義一個(gè)顏色輸出字符串函數(shù)
方法1: function?echo_color()?{ ????if?[?$1?==?"green"?];?then ????????echo?-e?"\033[32;40m$2\033[0m" ????elif?[?$1?==?"red"?];?then ????????echo?-e?"\033[31;40m$2\033[0m" ????fi } 方法2: function?echo_color()?{ ????case?$1?in ????????green) ????????????echo?-e?"[32;40m$2[0m" ????????????;; ????????red) ????????????echo?-e?"[31;40m$2[0m"? ????????????;; ????????*)? ????????????echo?"Example:?echo_color?red?string" ????esac } 使用方法:echo_color?green?"test" function關(guān)鍵字定義一個(gè)函數(shù),可加或不加。
3、批量創(chuàng)建用戶
#!/bin/bash DATE=$(date?+%F_%T) USER_FILE=user.txt echo_color(){ ????if?[?$1?==?"green"?];?then ????????echo?-e?"[32;40m$2[0m" ????elif?[?$1?==?"red"?];?then ????????echo?-e?"[31;40m$2[0m" ????fi } #?如果用戶文件存在并且大小大于0就備份 if?[?-s?$USER_FILE?];?then ????mv?$USER_FILE?${USER_FILE}-${DATE}.bak ????echo_color?green?"$USER_FILE?exist,?rename?${USER_FILE}-${DATE}.bak" fi echo?-e?"User Password"?>>?$USER_FILE echo?"----------------"?>>?$USER_FILE for?USER?in?user{1..10};?do ????if?!?id?$USER?&>/dev/null;?then ????????PASS=$(echo?$RANDOM?|md5sum?|cut?-c?1-8) ????????useradd?$USER ????????echo?$PASS?|passwd?--stdin?$USER?&>/dev/null ????????echo?-e?"$USER $PASS"?>>?$USER_FILE ????????echo?"$USER?User?create?successful." ????else ????????echo_color?red?"$USER?User?already?exists!" ????fi done
4、檢查軟件包是否安裝
#!/bin/bash if?rpm?-q?sysstat?&>/dev/null;?then ????echo?"sysstat?is?already?installed." else ????echo?"sysstat?is?not?installed!" fi
5、檢查服務(wù)狀態(tài)
#!/bin/bash PORT_C=$(ss?-anu?|grep?-c?123) PS_C=$(ps?-ef?|grep?ntpd?|grep?-vc?grep) if?[?$PORT_C?-eq?0?-o?$PS_C?-eq?0?];?then ????echo?"內(nèi)容"?|?mail?-s?"主題"?dst@example.com fi
6、檢查主機(jī)存活狀態(tài)
方法1:將錯(cuò)誤IP放到數(shù)組里面判斷是否ping失敗三次 #!/bin/bash?? IP_LIST="192.168.18.1?192.168.1.1?192.168.18.2" for?IP?in?$IP_LIST;?do ????NUM=1 ????while?[?$NUM?-le?3?];?do ????????if?ping?-c?1?$IP?>?/dev/null;?then ????????????echo?"$IP?Ping?is?successful." ????????????break ????????else ????????????#?echo?"$IP?Ping?is?failure?$NUM" ????????????FAIL_COUNT[$NUM]=$IP ????????????let?NUM++ ????????fi ????done ????if?[?${#FAIL_COUNT[*]}?-eq?3?];then ????????echo?"${FAIL_COUNT[1]}?Ping?is?failure!" ????????unset?FAIL_COUNT[*] ????fi done ???方法2:將錯(cuò)誤次數(shù)放到FAIL_COUNT變量里面判斷是否ping失敗三次 #!/bin/bash?? IP_LIST="192.168.18.1?192.168.1.1?192.168.18.2" for?IP?in?$IP_LIST;?do ????FAIL_COUNT=0 ????for?((i=1;i=3;i++));?do ????????if?ping?-c?1?$IP?>/dev/null;?then ????????????echo?"$IP?Ping?is?successful." ????????????break ????????else ????????????#?echo?"$IP?Ping?is?failure?$i" ????????????let?FAIL_COUNT++ ????????fi ????done ????if?[?$FAIL_COUNT?-eq?3?];?then ????????echo?"$IP?Ping?is?failure!" ????fi done 方法3:利用for循環(huán)將ping通就跳出循環(huán)繼續(xù),如果不跳出就會(huì)走到打印ping失敗 #!/bin/bash ping_success_status()?{ ????if?ping?-c?1?$IP?>/dev/null;?then ????????echo?"$IP?Ping?is?successful." ????????continue ????fi } IP_LIST="192.168.18.1?192.168.1.1?192.168.18.2" for?IP?in?$IP_LIST;?do ????ping_success_status ????ping_success_status ????ping_success_status ????echo?"$IP?Ping?is?failure!" done
7、監(jiān)控CPU、內(nèi)存和硬盤(pán)利用率
1)CPU 借助vmstat工具來(lái)分析CPU統(tǒng)計(jì)信息。 #!/bin/bash DATE=$(date?+%F"?"%H:%M) IP=$(ifconfig?eth0?|awk?-F??[?:]+???/inet?addr/{print?$4}?)??#?只支持CentOS6 MAIL="example@mail.com" if?!?which?vmstat?&>/dev/null;?then ????echo?"vmstat?command?no?found,?Please?install?procps?package."? ????exit?1 fi US=$(vmstat?|awk??NR==3{print?$13}?) SY=$(vmstat?|awk??NR==3{print?$14}?) IDLE=$(vmstat?|awk??NR==3{print?$15}?) WAIT=$(vmstat?|awk??NR==3{print?$16}?) USE=$(($US+$SY)) if?[?$USE?-ge?50?];?then ????echo?" ????Date:?$DATE ????Host:?$IP ????Problem:?CPU?utilization?$USE ????"?|?mail?-s?"CPU?Monitor"?$MAIL fi 2)內(nèi)存 #!/bin/bash DATE=$(date?+%F"?"%H:%M) IP=$(ifconfig?eth0?|awk?-F??[?:]+???/inet?addr/{print?$4}?)?? MAIL="example@mail.com" TOTAL=$(free?-m?|awk??/Mem/{print?$2}?) USE=$(free?-m?|awk??/Mem/{print?$3-$6-$7}?) FREE=$(($TOTAL-$USE)) #?內(nèi)存小于1G發(fā)送報(bào)警郵件 if?[?$FREE?-lt?1024?];?then ????echo?" ????Date:?$DATE ????Host:?$IP ????Problem:?Total=$TOTAL,Use=$USE,Free=$FREE ????"?|?mail?-s?"Memory?Monitor"?$MAIL fi 3)硬盤(pán) #!/bin/bash DATE=$(date?+%F"?"%H:%M) IP=$(ifconfig?eth0?|awk?-F??[?:]+???/inet?addr/{print?$4}?)?? MAIL="example@mail.com" TOTAL=$(fdisk?-l?|awk?-F?[:?]+???BEGIN{OFS="="}/^Disk?/dev/{printf?"%s=%sG,",$2,$3}?) PART_USE=$(df?-h?|awk??BEGIN{OFS="="}/^/dev/{print?$1,int($5),$6}?) for?i?in?$PART_USE;?do ????PART=$(echo?$i?|cut?-d"="?-f1) ????USE=$(echo?$i?|cut?-d"="?-f2) ????MOUNT=$(echo?$i?|cut?-d"="?-f3) ????if?[?$USE?-gt?80?];?then ????????echo?" ????????Date:?$DATE ????????Host:?$IP ????????Total:?$TOTAL ????????Problem:?$PART=$USE($MOUNT) ????????"?|?mail?-s?"Disk?Monitor"?$MAIL ????fi done
8、批量主機(jī)磁盤(pán)利用率監(jiān)控
前提監(jiān)控端和被監(jiān)控端SSH免交互登錄或者密鑰登錄。 寫(xiě)一個(gè)配置文件保存被監(jiān)控主機(jī)SSH連接信息,文件內(nèi)容格式:IP?User?Port #!/bin/bash HOST_INFO=host.info for?IP?in?$(awk??/^[^#]/{print?$1}??$HOST_INFO);?do ????USER=$(awk?-v?ip=$IP??ip==$1{print?$2}??$HOST_INFO) ????PORT=$(awk?-v?ip=$IP??ip==$1{print?$3}??$HOST_INFO) ????TMP_FILE=/tmp/disk.tmp ????ssh?-p?$PORT?$USER@$IP??df?-h??>?$TMP_FILE ????USE_RATE_LIST=$(awk??BEGIN{OFS="="}/^/dev/{print?$1,int($5)}??$TMP_FILE) ????for?USE_RATE?in?$USE_RATE_LIST;?do ????????PART_NAME=${USE_RATE%=*} ????????USE_RATE=${USE_RATE#*=} ????????if?[?$USE_RATE?-ge?80?];?then ????????????echo?"Warning:?$PART_NAME?Partition?usage?$USE_RATE%!" ????????fi ????done done
9、檢查網(wǎng)站可用性
1)檢查URL可用性 方法1: check_url()?{ ????HTTP_CODE=$(curl?-o?/dev/null?--connect-timeout?3?-s?-w?"%{http_code}"?$1) ????if?[?$HTTP_CODE?-ne?200?];?then ????????echo?"Warning:?$1?Access?failure!" ????fi } 方法2: check_url()?{ if?!?wget?-T?10?--tries=1?--spider?$1?>/dev/null?2>&1;?then?? #-T超時(shí)時(shí)間,--tries嘗試1次,--spider爬蟲(chóng)模式 ????????echo?"Warning:?$1?Access?failure!" ????fi } 使用方法:check_url?www.baidu.com 2)判斷三次URL可用性 思路與上面檢查主機(jī)存活狀態(tài)一樣。 方法1:利用循環(huán)技巧,如果成功就跳出當(dāng)前循環(huán),否則執(zhí)行到最后一行 #!/bin/bash?? check_url()?{ ????HTTP_CODE=$(curl?-o?/dev/null?--connect-timeout?3?-s?-w?"%{http_code}"?$1) ????if?[?$HTTP_CODE?-eq?200?];?then ????????continue ????fi } URL_LIST="www.baidu.com?www.agasgf.com" for?URL?in?$URL_LIST;?do ????check_url?$URL ????check_url?$URL ????check_url?$URL ????echo?"Warning:?$URL?Access?failure!" done ???方法2:錯(cuò)誤次數(shù)保存到變量 #!/bin/bash?? URL_LIST="www.baidu.com?www.agasgf.com" for?URL?in?$URL_LIST;?do ????FAIL_COUNT=0 ????for?((i=1;i=3;i++));?do ????????HTTP_CODE=$(curl?-o?/dev/null?--connect-timeout?3?-s?-w?"%{http_code}"?$URL) ????????if?[?$HTTP_CODE?-ne?200?];?then ????????????let?FAIL_COUNT++ ????????else ????????????break ????????fi ????done ????if?[?$FAIL_COUNT?-eq?3?];?then ????????echo?"Warning:?$URL?Access?failure!" ????fi done ???方法3:錯(cuò)誤次數(shù)保存到數(shù)組 #!/bin/bash?? URL_LIST="www.baidu.com?www.agasgf.com" for?URL?in?$URL_LIST;?do ????NUM=1 ????while?[?$NUM?-le?3?];?do ????????HTTP_CODE=$(curl?-o?/dev/null?--connect-timeout?3?-s?-w?"%{http_code}"?$URL) ????????if?[?$HTTP_CODE?-ne?200?];?then ????????????FAIL_COUNT[$NUM]=$IP??#創(chuàng)建數(shù)組,以$NUM下標(biāo),$IP元素 ????????????let?NUM++ ????????else ????????????break ????????fi ????done ????if?[?${#FAIL_COUNT[*]}?-eq?3?];?then ????????echo?"Warning:?$URL?Access?failure!" ????????unset?FAIL_COUNT[*]????#清空數(shù)組 ????fi done
10、檢查MySQL主從同步狀態(tài)
#!/bin/bash?? USER=bak PASSWD=123456 IO_SQL_STATUS=$(mysql?-u$USER?-p$PASSWD?-e??show?slave?statusG??|awk?-F:??/Slave_.*_Running/{gsub(":?",":");print?$0}?)??#gsub去除冒號(hào)后面的空格 for?i?in?$IO_SQL_STATUS;?do ????THREAD_STATUS_NAME=${i%:*} ????THREAD_STATUS=${i#*:} ????if?[?"$THREAD_STATUS"?!=?"Yes"?];?then ????????echo?"Error:?MySQL?Master-Slave?$THREAD_STATUS_NAME?status?is?$THREAD_STATUS!" ????fi done
動(dòng)手練一練,讓你的Shell功底上升一個(gè)段位!
未完待續(xù)...
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。