熟悉基本shell操做不只是運維的基本功,對於開發來講也是多多益善,我在學習的過程當中,總結了十個練手的小demo,並附上涉及的知識點,僅供娛樂。html
& 表示任務在後臺執行,如要在後臺運行redis-server,則有 redis-server &
&& 表示前一條命令執行成功時,才執行後一條命令 ,如 echo '1‘ && echo '2'
| 表示管道,上一條命令的輸出,做爲下一條命令參數,如 echo 'yes' | wc -l
|| 表示上一條命令執行失敗後,才執行下一條命令,如 cat nofile || echo "fail"redis
ping 命令語法shell
ping [-dfnqrRv][-c<完成次數>][-i<間隔秒數>][-I<網絡界面>][-l<前置載入>][-p<範本樣式>][-s<數據包大小>][-t<存活數值>][主機名稱或IP地址]
#!/bin/bash #使用&開啓後臺進程 net="101.200.35" mult_ping() { ping -c2 -i0.2 -W1 $1 &>/dev/null if [ $? -eq 0 ];then echo "$1 is up" else echo "$1 is down" fi } for i in {0..255} do mult_ping $net.$i & done wait
#!/bin/bash trap 'kill $!' INT # 定義寬度爲50的進度條 # 輸出完成後將/r光標切換到行首,準備下一次進度條顯示 bar () { while : pound="" for ((i = 47; i>=1; i-- )) do pound += # printf "|%s%${i}s|\r" "$pound" sleep 0.2 done } # 調用函數,顯示進度符號,直到複製結束kill進度函數 bar & cp -r $1 $2 kill $! echo "複製結束"
分析工具:pstree 進程樹數組
文件描述符是一個非負整數,而內核須要經過這個文件描述符才能夠訪問文件。當咱們在系統中打開已有的文件或新建文件時,內核每次都會給特定的進程返回一個文件描述符,當進程須要對文件進行讀或寫操做時,都要依賴這個文件描述符進行。文件描述符就像一本書的目錄頁數(也叫索引),經過這個索引能夠找到須要的內容。在 Linux 或類 UNIX系統中內核默認會爲每一個進程建立三個標準的文件描述符,分別是 0(標準輸入)、 1(標準輸出)和 2(標準錯誤)。經過查看/proc/PID 號/fd/目錄下的文件,就能夠查看每一個進程擁有的全部文件描述符。bash
建立文件描述符:網絡
exec 文件描述符 <> 文件名
調用文件描述符語法格式:多線程
&文件描述符
關閉文件描述符:併發
exec 文件描述符<&- exec 文件描述符>&-
管道是進程間通訊的一種方式,匿名管道,使用|符號就能夠建立一個匿名管道,顧名思義,系統會自動建立一個能夠讀寫數據的管道,可是這個管道並無名稱。一個程序往管道中寫數據,另外一個程序就能夠從管道中讀取數據。可是匿名管道僅能夠實現父進程與子進程之間的數據交換,能不能實現任意兩個無關的進程之間的通訊呢?答案是確定的,使用命名管道,也叫FIFO1文件。運維
命名管道的特徵:curl
第一個demo中,經過 & 開啓任意數量線程進行ping,可是這裏的線程不可控。咱們用上面的文件描述符和命名管道的知識,寫一段可控的多線程ping。
#!/bin/bash pipefile=/tmp/procs_$$.temp num=10 net="101.200.35" multi_ping() { ping -c2 -i0.2 -W1 $1 &>/dev/null if [ $? -eq 0 ];then echo "$1 is up" else echo "$1 is down" fi } # 建立命名管道文件,建立其文件描述符,經過重定向將數據導入管道文件 mkfifo $pipefile exec 12<>$pipefile for i in `seq $num` do echo "" >&12 & done # 成功讀取命名管道中的數據後開啓新的進程 # 全部內容讀取完以後read被阻塞,沒法再啓動新的進程 # 等待前面啓動的線程結束後,繼續往管道文件中寫入數據,釋放阻塞,再次開啓新的線程 for j in {1..254} do read -u12 { multi_ping $net.$j echo "" >&12 } & done wait rm -rf $pipfile
下載思路:用curl獲取網站源代碼+sed數據清洗獲取圖片地址+wget下載保存
#!/bin/bash # 爬取美女圖片 # 定義要爬取的網站和保存的文件 page="https://tieba.baidu.com/p/4420470629" URL="beau.txt" # 將網站源代碼保存到文件中 curl -s https://tieba.baidu.com/p/4420470629 > $URL # 對源代碼數據過濾清洗,獲取種子的URL連接 echo -e "\033[32m 正在獲取種子 URL,請稍後...\033[0m" sed -i '/<img/!d' $URL #刪除不包含<img 的行 sed -i 's/.*src="//' $URL #刪除 src="及其前面的全部內容 sed -i 's/".*//' $URL #刪除雙引號及其後面的全部內容 echo #利用循環批量下載全部圖片數據 #wget 爲下載工具,其參數選項描述以下: # -P 指定將數據下載到特定目錄(prefix) # -c 支持斷點續傳(continue) # -q 不顯示下載過程(quiet) echo -e "\033[32m 正在批量下載種子數據,請稍後...\033[0m" for i in $(cat $URL) do wget -P tempPhoto/ -c $i done
這種知識最基本的爬蟲,對於反爬蟲的網站就嗝屁了,對於那種異步加載的也沒辦法,總之,就是比較弱。
作一個互聯網大佬的隨機點名器
#!/bin/bash #按 Ctrl+C 組合鍵時:恢復光標,恢復終端屬性,清屏,退出腳本 #防止程序意外中斷致使的終端混亂 trap 'tput cnorm;stty $save_property;clear;exit' 2 #定義變量:人員列表文件名,文件的行數,屏幕的行數,屏幕的列數 name_file="name.txt" line_file=$(sed -n '$=' $name_file) line_screen=`tput lines` column_screen=`tput cols` #設置終端屬性 save_property=$(stty -g) #保存當前終端全部屬性 tput civis #關閉光標 #隨機抽取一我的名(隨機點名) while : do tmp=$(sed -n "$[RANDOM%line_file+1]p" $name_file) #隨機獲取文件的某一行人名 tput clear #清屏 tput cup $[line_screen/4] $[column_screen/4] echo -e "\033[3;5H 隨機點名器(按 P 中止): " echo -e "\033[4;5H#############################" echo -e "\033[5;5H# #" echo -e "\033[6;5H#\t\t$tmp\t\t#" echo -e "\033[7;5H# #" echo -e "\033[8;5H#############################" sleep 0.1 stty -echo read -n1 -t0.1 input if [[ $input == "p" || $input == "P" ]];then break fi done tput cnorm #恢復光標 stty $save_property #恢復終端屬性
[-F|-f|-v] 大參數,-F指定分隔符,-f調用腳本,-v定義變量 var=value
#!/bin/bash # 監控網絡鏈接狀態 #全部 TCP 鏈接的個數 TCP_Total=$(ss -s | awk '$1=="TCP"{print $2}') #全部 UDP 鏈接的個數 UDP_Total=$(ss -s | awk '$1=="UDP"{print $2}') #全部 UNIX sockets 鏈接個數 Unix_sockets_Total=$(ss -ax | awk 'BEGIN{count=0} {count++} END{print count}') #全部處於 Listen 監聽狀態的 TCP 端口個數 TCP_Listen_Total=$(ss -antlpH | awk 'BEGIN{count=0} {count++} END{print count}') #全部處於 ESTABLISHED 狀態的 TCP 鏈接個數 TCP_Estab_Total=$(ss -antpH | awk 'BEGIN{count=0} /^ESTAB/{count++} END{print count}') #全部處於 SYN-RECV 狀態的 TCP 鏈接個數 TCP_SYN_RECV_Total=$(ss -antpH | awk 'BEGIN{count=0} /^SYN-RECV/{count++} END{print count}') #全部處於 TIME-WAIT 狀態的 TCP 鏈接個數 TCP_TIME_WAIT_Total=$(ss -antpH | awk 'BEGIN{count=0} /^TIME-WAIT/{count++} END{print count}') #全部處於 TIME-WAIT1 狀態的 TCP 鏈接個數 TCP_TIME_WAIT1_Total=$(ss -antpH | awk 'BEGIN{count=0} /^TIME-WAIT1/{count++} END{print count}') #全部處於 TIME-WAIT2 狀態的 TCP 鏈接個數 TCP_TIME_WAIT2_Total=$(ss -antpH | awk 'BEGIN{count=0} /^TIME-WAIT2/{count++} END{print count}') #全部遠程主機的 TCP 鏈接次數 TCP_Remote_Count=$(ss -antH | awk '$1!~/LISTEN/{IP[$5]++} END{ for(i in IP){print IP[i],i} }' | sort -nr) #每一個端口被訪問的次數 TCP_Port_Count=$(ss -antH | sed -r 's/ +/ /g' | awk -F"[ :]" '$1!~/LISTEN/{port[$5]++} END{for(i in port){print port[i],i}}' | sort -nr) #定義輸出顏色 SUCCESS="echo -en \\033[1;32m" #綠色 NORMAL="echo -en \\033[0;39m" #黑色 #顯示 TCP 鏈接總數 tcp_total(){ echo -n "TCP 鏈接總數: " $SUCCESS echo "$TCP_Total" $NORMAL } #顯示處於 LISTEN 狀態的 TCP 端口個數 tcp_listen(){ echo -n "處於 LISTEN 狀態的 TCP 端口個數: " $SUCCESS echo "$TCP_Listen_Total" $NORMAL } #顯示處於 ESTABLISHED 狀態的 TCP 鏈接個數 tcp_estab(){ echo -n "處於 ESTAB 狀態的 TCP 鏈接個數: " $SUCCESS echo "$TCP_Estab_Total" $NORMAL } #顯示處於 SYN-RECV 狀態的 TCP 鏈接個數 tcp_syn_recv(){ echo -n "處於 SYN-RECV 狀態的 TCP 鏈接個數: " $SUCCESS echo "$TCP_SYN_RECV_Total" $NORMAL } #顯示處於 TIME-WAIT 狀態的 TCP 鏈接個數 tcp_time_wait(){ echo -n "處於 TIME-WAIT1 狀態的 TCP 鏈接個數: " $SUCCESS echo "$TCP_TIME_WAIT1_Total" $NORMAL } #顯示處於 TIME-WAIT2 狀態的 TCP 鏈接個數 tcp_time_wait2(){ echo -n "處於 TIME-WAIT2 狀態的 TCP 鏈接個數: " $SUCCESS echo "$TCP_TIME_WAIT2_Total" $NORMAL } #顯示 UDP 鏈接總數 udp_total(){ echo -n "UDP 鏈接總數: " $SUCCESS echo "$UDP_Total" $NORMAL } #顯示 UNIX sockets 鏈接總數 unix_total(){ echo -n "Unix sockets 鏈接總數: " $SUCCESS echo "$Unix_sockets_Total" $NORMAL } #顯示每一個遠程主機的訪問次數 remote_count(){ echo "每一個遠程主機與本機的併發鏈接數: " $SUCCESS echo "$TCP_Remote_Count" $NORMAL } #顯示每一個端口的併發鏈接數 port_count(){ echo "每一個端口的併發鏈接數: " $SUCCESS echo "$TCP_Port_Count" $NORMAL } print_info(){ echo -e "------------------------------------------------------" $1 } print_info tcp_total print_info tcp_listen print_info tcp_estab print_info tcp_syn_recv print_info tcp_time_wait print_info tcp_time_wait1 print_info tcp_time_wait2 print_info udp_total print_info unix_total print_info remote_count print_info port_count echo -e "------------------------------------------------------"
參考