Linux阶段总结shell脚本
生活随笔
收集整理的這篇文章主要介紹了
Linux阶段总结shell脚本
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
shell腳本知識儲備匯總
語言類型
強類型:定義變量必須指定類型;參與的運算必須要符合類型要求(字符串不能和數值相加等);調用未聲明變量會報錯弱類型:定義變量無需指定類型;默認為字符型參與運算時會自動進行類型轉換;變量無需事先定義也可調用(空)解釋器:
shell是解釋器bash是可用的具體解釋器(shell是車這個概念bash是寶馬車)bash sh ksh(需自己安裝) tcsh csh等 bash的基本特性:快捷鍵;Tab補齊命令和路徑;history;命令別名;標準輸入輸出;重定向;管道;Redhat6選項不可Tab 需要裝bash-completion這個包才能Tab更改用戶shell環境(解釋器): useradd -s 創建用戶時usermod -s 改已存在用戶vim /etc/passwd 改配置history:查看條數: grep HISTSIZE /etc/profileecho $HISTSIZEhistory | wc -lhistory | tail調用: !1028!cat清空(兩條命令必須同時執行):history -c > ~/.bash_history 空重定向到HISTFILE文件別名alias: grep '^alias' ~/.bashrc 家目錄下的隱藏文件unalias 取消重定向:
> (正確覆蓋輸出);>> (正確追加輸出);2> (錯誤覆蓋輸出);2>> (錯誤覆蓋輸出);&> (正確錯誤覆蓋輸出);&>> (正確錯誤追加輸出);>&2 把正確變成錯誤輸出<; (導入文件) tips: 寫腳本可以上來就date >(>>) xx.log 再在里面把命令執行錯誤的信息2>(>>) xx.log以執行時間 進行區分了方便查看某次執行時的錯誤非交互式寫郵件三種:mail -s biaoti user <<EOFXXYYEOFecho haha | mail -s biaoti user 管道mail -s biaoti user < mail.txt 導入寫好文件腳本的執行方式:
/root/first.sh ./first.sh 絕對路徑(相對)執行 需+xbash、sh /root/first.sh 解釋器執行(相當于作為參數)不需+x 開了子進程pstree可以驗證source、./root/first.sh 解釋器執行(相當于作為參數) 不需+x 當前進程執行用于使改的配置馬上生效而不重啟,相當于重讀配置文件。shell變量:
變量的類型儲值類型:數值型 :整數型;浮點型;復數。。。字符型 :生效范圍:本地變量:當前Shell環境中有效,而在子Shell環境中無法直接使用 局部變量:全局變量:使用類型:自定義變量: a=1 echo ${a}10 110 本地變量TIPS:查看變量時,若變量名稱與后面要輸出的字符串連在一起,則應該以{}將變量名括起來以便區分環境變量: PWD、USER、HOME、SHELL、HISTSIZE、HISTFILE、PATH、PS1一級提示符、PS2二級提示符、LOGNAME登錄名 RANDOM HOSTNAME TERM記錄終端類型環境變量相關文件:(注意開機時讀取文件順序)全局文件為/etc/profile,對所有用戶有效 用戶文件為~/.bash_profile,僅對指定的用戶有效env可查看所有環境變量:set可查看所有變量 位置變量: $1、$2、$10、……預定義變量: $0、$$、$?、$#、$*、$@ #!/bin/bashecho $0 //腳本的名稱echo $1 //第一個參數echo $2 //第二個參數echo $* //所有參數 當成一個整體字符串echo $@ //所有參數 每個參數為獨立字符串echo $# //輸入的位置變量個數echo $$ //當前進程的進程號echo $? //上一個命令執行狀態返回值echo $! // 最后一個后臺進程的進程號shift 3 //換崗 踢掉參數(默認為一個)使用read命令從鍵盤讀取變量值read -p "請輸入。。:" i 用戶輸入的值賦予變量i將回顯功能關閉(stty -echo) 輸password時將回顯功能恢復(stty echo) 輸完password時使用export發布全局變量 export PATH="$PATH:/usr/local/haha/bin"臨時加了個可執行路徑。export XX="1234" 變量的定義: 名稱只能為字母數字下劃線且只能以字母和下劃線開頭a=123 字符串a=$b 引用其他變量的值為自己的值a=$(date) 命令結果引用為自己的值三種引號對賦值的影響:強引用: 雙引號 界定一個完整字符串弱引用: 單引號 界定一個完整的字符串且屏蔽特殊符號命令結果引用: 反撇號或$() 引用命令執行的結果賦予變量 變量的調用調用變量時,若變量名稱與后面輸出的字符串連在一起,以{}將變量名括起來以便區分shell的數值運算
整數運算:expr \*$[]或$(()) 運算符兩側可以無空格 引用變量可省略 $let 不顯示結果expr或$[]、$(())方式只進行運算,并不會改變變量的值;而let命令可以直接對變量值做運算再保存新的值let X++ X-- X+=7 X-=7 X*=7 X/=7 X%=7 強大!!小數運算:bc scale=N 小數位的長度echo 'scale=4;12.34-5.678' | bc 6.662 雖然小數位長為4但運算數值最長為3 也只顯示3位。tips:bc支持條件測試正確返回1錯誤返回0 與$?相反條件測試
“test 表達式”或者[ 表達式 ]都可以,表達式兩邊至少要留一個空格。注意空格空格空格![ $USER == "root" ] 等號兩邊有空格(沒有就相當字符串a) 表達式和[]間有空格!!!字符串匹配== != -z 檢查變量的值是否為空 -n或!-z 檢查變量的值是否非空 比較整數值的大小eq ne gt ge lt le識別文件/目錄的狀態-e存在 -d目錄 -f普通文件 -r讀 -w寫 -x執行多個條件/操作的邏輯組合&&,邏輯與 第一個為假后面都不用執行||, 邏輯或 第一個為真后面都不用執行!,邏輯非短路運算:[ $X -gt 10 ] && echo "YES" || echo "NO"第一個為真必須yes而不會No了,因為前面整體為真了||運算已經結束。或者永遠只判斷邏輯符號的前一條命令來推導該命令會不會執行。if選擇結構
單分支就直接: [ $X -gt 10 ] && echo "YES"雙分支: [ $X -gt 10 ] && echo "YES" || echo "NO"if [ 條件測試 ];then 命令序列1else 命令序列2fi多分支: if [ 條件測試 ];then 命令序列1 執行完就exitelif命令序列2 執行完就exitelse 命令序列3 執行完就exitfi案例:檢測/media/cdrom目錄,若不存在則創建檢測并判斷指定的主機是否可ping通ping -c 3 -i 0.2 -W 3 192.168.4.5 -c 3(3次)-i0.2間隔0.2秒-W 3反饋的超時秒數3從鍵盤讀取一個論壇積分,判斷論壇用戶等級被閹割的選擇結構case
case分支屬于匹配執行的方式,它針對指定的變量預先設置一個可能的取值,判斷該變量的實際取值是否與預設的某一個值相匹配,如果匹配上了,就執行相應的一組操作,如果沒有任何值能夠匹配,就執行預先設 置的默認操作。case 變量值 in模式1)命令序列1 ;;模式2)命令序列2 ;; 注意格式!!!必須是雙分號。。.. ..*)默認命令序列esac#!/bin/bashcase $1 inredhat) //可以換成-n-i來代表選項做一個功能強大的命令出來echo "fedora";;fedora)echo "redhat";;*) //默認輸出腳本用法echo "用法: $0 {redhat|fedora}"esac循環結構
for循環for 變量名 in 值列表或 {1..5} 或 `seq 5` 或((i=1;i<=5;i++))do命令序列done幾個循環造數工具{1..n}seq 5(1開始到5) seq 2 10(2開始到10)seq 2 2 10(2開始中間跳2;即偶數)seq 1 2 10(奇數)[$RANDOM%10+1] 隨機產生1-10的數((i=1;i<=5;i++)) 初值1;條件<=5;步長為1案例:利用for循環來檢測多個主機的存活狀態while循環 while [條件測試]do命令序列done死循環一般格式 while :do命令序列done通常會寫成死循環加退出的格式while :doif[條件判斷];then命令序列 && breakdone案例: 提示用戶猜測一個隨機數,直到才對為止檢測192.168.4.0/24網段,列出不在線的主機地址shell函數
將一些需重復使用的操作,定義為公共的語句塊,即可稱為函數。通過使用函數,可以使腳本代碼更加簡潔,增強易 讀性,提高Shell腳本的執行效率相當于一段代碼(一串命令)取了一個名字類似定義了alias定義錯了直接重新定義會覆蓋,類似a=1;a=2后會覆蓋前。function 函數名 {命令序列.. ..}函數名() {命令序列.. ..} mycd(){ //定義函數> mkdir $1> cd $1> }案例:顏色輸出的命令:echo -e "\033[32;41mOK\033[0m"。3X為字體顏色分號隔開4X為背景顏色。#!/bin/bashcecho() {echo –e "\033[$1m$2\033[0m"}cecho 32 OKcecho 33 OKcecho 34 OKcecho 35 OK中斷和退出
break可以結束整個循環;continue結束本次循環,進入下一次循環;exit結束整個腳本、#!/bin/bashfor i in {1..5}do[ $i -eq 3 ]&& break //這里將break替換為continue,exit分別測試腳本執行效果 echo $idoneecho Overbreak 12Over continue 1245Over exit 12案例:求輸入數的和輸0退出#!/bin/bashwhile read -p "請輸入待累加的整數(0表示結束):" xdo[ $x -eq 0 ] && breakSUM=$[SUM+x]doneecho "總和是:$SUM"案例:求1-20內所有數的平方跳過非6的倍數#!/bin/bashi=0while [ $i -le 20 ]dolet i++[ $[i%6] -ne 0 ] && continueecho $[i*i]doneexit 2文本處理
字符串截取及切割echo $變量名 | cut -b 起始位置-結束位置 echo $phone | cut -b 1-6 1-6echo $phone | cut -b 8- 8到最后echo $phone | cut -b 9 第9個echo $phone | cut -b 3,5,8 第3 5 8個expr substr "$變量名" 起始位置 長度${變量名:起始位置:長度} 截取 (索引位置) ${phone:0:6} ${phone::6} ${變量名/old/new} 替換第一個${變量名//old/new} 替換全部${變量名#*關鍵詞} (關鍵詞也刪)左向右 最短匹配刪除 ${A#*:} 從左側到第一個:的所有${變量名##*關鍵詞} 左向右 最長匹配刪除 ${A##*:}從左側到最后一個:的所有 ${變量名%關鍵詞*} 右向左 最短匹配刪除 ${A%:*} 從右側到第一個:的所有${變量名%%關鍵詞*} 右向左 最長匹配刪除 ${A##*:}從右側到最后一個:的所有 ${變量名:-初值} 有初值就用初值 無初值就用賦予的初值 ${XX:-123}xx無初值就賦予123為初值隨機密碼 #!/bin/bashx=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789//所有密碼的可能性是26+26+10=62(0-61是62個數字)for i in {1..8}donum=$[RANDOM%62]tmp=${x:num:1}pass=${pass}$tmp 字符串相加doneecho $pass改擴展名 touch {a,b,c,d,e,f,g,h,i}.doc#!/bin/bashfor FILE in `ls *.doc($1)`domv $FILE ${FILE%.*}.txt("$2") (${FILE/doc/txt}) $1換成$2的擴展名done初值的處理 #!/bin/bashread -p "請輸入一個正整數:" xx=${x:-1}i=1; SUM=0while [ $i -le $x ]dolet SUM+=ilet i++doneecho "從1到$x的總和是:$SUM"#!/bin/bashread -p "請輸入用戶名:" userread -p "請輸入用戶名:" pass[ -z $user ] && exit //如果無用戶名,則腳本退出pass=${pass:-123456} //如果用戶沒有輸入密碼,則默認密碼為123456useradd $userecho "$pass" | passwd --stdin $passexpect預期交互 :模擬人機交互過程(要提前對交互過程非常熟悉)install expect#!/bin/bashfor i in 10 11 {1..245} seq 1 254doexpect << EOFspawn ssh -o StrictHostKeyChecking=no 172.25.0.$i #//創建交互式進程 expect "password:" { send "123456\r" } #//自動發送密碼expect "# { send "pwd > /tmp/$user.txt \r" } #//發送命令expect "#" { send "exit\r" }EOFdoneexpect腳本的最后一行默認不執行如果不希望ssh時出現yes/no的提示,遠程時使用如下選項:# ssh -o StrictHostKeyChecking=no server0shell數組整體賦值:a=(haha xixi hehe ) a[0]=haha 0是索引值為0的量單個賦值:a[0]=haha a[1]=xixia[2]=hehe文本處理三劍客grep
三劍客都用''單引號!正則表達式
字符匹配(單個字符).點 任意單個字符[] [xyz] 集合,里面的任意單個字符[a-z] [:lower:][A-Z] [:upper:][a-Z] [:alpha:][0-9] [:digit:][0-9a-Z] [:alnum:][:space:] [^] [^xyz] 集合取反 [^a-z][^A-Z][^a-Z][^0-9][^0-9a-Z]|(擴展)x|y 或者匹配次數 * 前一個字符出現任意次\{n,m\} 前一字符出現n到m次\{n} 前一字符出現n次\{n,\} 前一字符至少出現n次\(\) 保留(復制)后向引用次數匹配(擴展)+ 至少出現1次? 出現0次或1次{n} 出現n次{n,} 至少出現n次 {n,m} 出現n到m次{0,m} 至多出現m次位置錨定 ^ 匹配行首(以什么開頭)$ 匹配行尾(以什么結尾)\> 詞尾 \< 詞首 \b(擴展) 單詞邊界^$^[[:space:]]*$ 后向引用() 組合為整體,保留(復制)分組(復制) ( )復制 \1 \2 \3 粘貼\B 匹配非單詞邊界“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。? 當該字符緊跟在任何一個其他限制符(*,+,?,{n},{n,},{n,m})后面時,匹配模式是非貪婪的非貪婪模式盡可能少地匹配所搜索的字符串,而默認的貪婪模式則盡可能多地匹配所搜索的字符串例如,對于字符串“oooo”,“o+”將盡可能多地匹配“o”,得到結果[“oooo”]而“o+?”將盡可能少地匹配“o”,得到結果 ['o', 'o', 'o', 'o']正則表達式過濾案例:
egrep -c '/sbin/nologin$' /etc/passwd = egrep '/sbin/nologin$' /etc/passwd | wc -l 內置了統計功能egrep -vc '/sbin/nologin$' /etc/passwd egrep -cv '.' /etc/rc.local 統計空行egrep -c '^$' /etc/rc.local 統計空行egrep -c ".*" /etc/httpd/conf/httpd.conf //總行數egrep -c "#" /etc/httpd/conf/httpd.conf //含注釋的行數egrep -c -v '#|^$' /etc/httpd/conf/httpd.conf 有效配置行(多數配置文件適用)egrep -v '#|^$' /etc/httpd/conf/httpd.conf > httpd.conf.min 保存有效配置行egrep '^ .+|^[^#]' test5-19-1.sh 腳本里真正的有效配置的行?具體情況具體分析啊egrep -m 2 '/sbin/nologin$' /etc/passwd 只顯示匹配到的前2行 egrep '.*' /etc/rc.local 匹配所有egrep 'exec(ution)*' /etc/rc.local 包含exec 和execution的行ifconfig | egrep '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' 包含MAC地址MAC03="20:69:74:R2:C5:27" 判斷mac地址是否有效echo $MAC03 | egrep -q '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' && echo "有效" || echo "無效"過濾有效的郵箱地址egrep '[0-9a-zA-Z_.]{3,}@[0-9a-zA-Z.-]{2,}(\.[0-9a-zA-Z-]{2,})+' mail.txt sort -t: -k3 -n /etc/passwd |tail -1 | cut -d: -f3 UID最大的用戶名精確匹配root用戶(3種方式)egrep '^\broot\b' /etc/passwdegrep '^\<root\>' /etc/passwd awk -F: '$1=="root"' /etc/passwd如果root存在顯示它的解釋器id root &> /dev/null && egrep '^\broot\b' /etc/passwd | cut -d: -f7id root &> /dev/null && awk -F: '$1=="root"{print $NF}' /etc/passwdegrep '\b[0-9]{2,3}\b' /etc/passwd 2-3位數字某個腳本的有效語句:egrep '^[^#]' test5-19-1.sh | egrep '[^[:space:]]+.*#.*' 這個好惱火啊egrep '^[^#]|[^[:space:]]+.*#.*' test5-19-1.sh 用戶名同shell名的:egrep '(^\b[a-Z0-9]+\b).*\1$' /etc/passwdsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltbash:x:1005:1025::/home/bash:/bin/bashnologin:x:1008:1028::/home/nologin:/sbin/nologin案例:傳遞兩個文件作為參數給腳本計算這兩個文件所有空白行之和 k1=$(egrep "^[[:space:]]*$" $1 | wc -lk2=$(egrep "^[[:space:]]*$" $2 | wc -l echo "$[k1+k2]" root centos user1用戶的默認shell和uid/etc/grub2.cfg文件中某單詞后面跟一個小括號的行使用echo輸出一個絕對路徑egrep找出其基名和目錄名ifconfig結果中1-255之間的數值(大量用|或者)ifconfig結果中的IP地址文本處理三劍客sed:
逐行處理軟件 讀一行處理一行 逐行處理讀一行處理一行。sed [選項] '條件指令' 文件選項:-n 屏蔽默認輸出-r 支持擴展正則-i 修改源文件條件:行號 4 4;5 4,5 4,+10 4~2(第4行和后面步長為2的行)sed -n '2~2P' sed.txt 偶數行sed -n '1~2P' sed.txt 奇數行 sed -n '$=' a.txt //輸出文件的行數/正則/sed -n 'p' a.txt //輸出所有行,等同于cat a.txtsed -n '4p' a.txt //輸出第4行sed -n '4,7p' a.txt //輸出第4~7行sed -n '4,+10p' a.txt //輸出第4行及其后的10行內容sed -n '/^bin/p' a.txt //輸出以bin開頭的行sed '/xml/!d' a.txt //刪除不包含xml的行,!符號表示取反sed '$d' a.txt //刪除文件的最后一行sed '/^$/d' a.txt //刪除所有空行tips: sed 's/xml//g' a.txt //將所有的xml都刪除(替換為空串)sed -n 's/2017/xxxx/gp' sed.txt //替換所有并打印sed 's/xml/XML/' a.txt //將每行中第一個xml替換為XMLsed 's/xml/XML/3' a.txt //將每行中的第3個xml替換為XMLsed 's/xml/XML/g' a.txt //將所有的xml都替換為XMLsed 's/xml//g' a.txt //將所有的xml都刪除(替換為空串)sed 's#/bin/bash#/sbin/sh#' a.txt //將/bin/bash替換為/sbin/sh (涉及到路徑時用其他符合分隔)sed '4,7s/^/#/' a.txt //將第4~7行注釋掉(行首加#號)sed 's/^#an/an/' a.txt //解除以#an開頭的行的注釋(去除行首的#號)sed -n 's/.//2;s/.$//p' sed.txt 刪除文件中每行的第二個、最后一個字互換:(后向引用)sed -rn 's/^(.)(.*)(.)$/\3\2\1/p' sed.txt 第一個、倒數第1個字符互換sed -rn 's/^(.)(.)(.*)(.)(.)$/\1\4\3\2\5/p' sed.txt 第二第四互換注意:做對換時空格也算如果測試文件中首尾都是空格的話看不出效果首為R 尾為空格視覺效果是把R放到最后去了。sed 's/[0-9]//' nssw.txt 刪除文件中所有的數字sed -r 's/[0-9]//g;s/^( )+//' nssw2.txt 刪除所有數字、行首空格sed -rn 's/([A-Z])/[\1]/gp' nssw.txt 為文件中每個大寫字母添加括號sed -rn 's/([a-Z0-9])/[\1]/gp' sed.txt 為文件中每個字母和數字添加括號sed -rn 's/([a-Z0-9 ])/(\1)/gp' sed.txt 為文件中每個字母和數字空格添加括號sed 導入導出操作:r動作與i選項配合才會存入,否則只會輸出讀取文件: 3r b.txt 4,7r b.txt 第3行下方插入b;第 4-7行每行下插入bw動作以覆蓋的方式另存為新文件另存為文件:3w c.txt 4,7w c.tx 將第三行另存為;將第4-7行另存為sed復制粘貼:模式空間:存放當前處理的行 若當前處理行不符合處理條件則原樣輸出 處理完當前行再讀入下一行來處理保持空間:左右類似剪貼板默認存放一個空行(換行符\n :回車)h 模式空間——》覆蓋———》保持空間 復制H 模式空間——》追加———》保持空間 復制g 模式空間——》覆蓋———》保持空間 粘貼G 模式空間——》追加———》保持空間 粘貼sed '3h;3d;5g;' sed.txtsed '3h;3d;5G' sed.txtsed '3g' sed.txt 第三行變空格。指令:p 打印d 刪除s 替換s/舊/新/ga 指定行之后追加 sed '2a XX' a.txt //在第二行后面,追加XXi 指定行之前插入sed '2i XX' a.txt //在第二行前面,插入XXc 替換行sed '2c XX' a.txt //將第二行替換為XXsed '1c mysvr.tarena.com' /etc/hostname 修改主機名腳本中修改配置文件時:cp /etc/vsftpd/vsftpd.conf{,.bak} 給配置文件備份/etc/hosts 這個文件非常有用:優先級比dns高 本地解析庫sed -i '$a 192.168.4.20 D ' /etc/hosts這樣就可以ssh D 直接遠程這個ip了。sed -i '$a 192.168.4.20 www.baidu.com ' /etc/hosts這樣訪問百度就快些了不用去找dns解析了文本處理三劍客awk:
awk [選項] '[條件]{指令}' 文件 多條編輯指令,可用分號分隔默認將空格、制表符等作為分隔符 (cut sort 也是是默認空格Tab)grep sed 不能直接打印某列要結合字符串的截取工具使用-F 可指定分隔符 識別多種單個的字符 awk -F [:/] '{print $1,$10}' /etc/passwdawk常用內置變量:$0 文本當前行的全部內容$1 文本的第1列$3 文件的第3列,依此類推NR 文件當前行的行號NF 文件當前行的列數(有幾列awk -F: '{print NR,NF}' passwd.txtawk -F: '{print NR,$NF}' /etc/passwd 永遠打印最后一行!awk -F: '{print NR,$NR}' /etc/passwd 第幾行的時候就打印第幾列!可以打印常量:awk -F: '{print $1,"的解釋器:",$7}' /etc/passwd 打印常量必須要加雙引號, 加逗號有空格,不加逗號無空格!案例: free |awk '/Mem/{print $NF}' 查看目前可用內存ifconfig eth0 | awk '/RX p/{print $5}' 查看接收流量!ifconfig eth0 | awk '/TX p/{print $5}' 查看發送流量!df -h | awk '/\/$/{print $4}' #:\/$代表對/轉義!!看跟分區可用空間。df | awk '/\/$/{print $4}' 故意不加單位 在腳本中好當成數值比較!!!df -h / | tail -1 | awk '{print $4}' 第一個/ 代表要看/(根)的情況 提取最后一行 給awk在網頁中查看腳本:遠程監控服務器網卡 內存等等情況(相當于動態頁面了)rpm -qa | grep httpdcp /root/share/test5-19-1.sh /var/www/cgi-bin/test5-19-1.html 必須放在腳本專用目錄下chmod +x /var/www/cgi-bin/test5-19-1.html 必須要加X不然訪問不了要報404. 看到404就檢查有沒有Xsystemctl stop firewalldsetenforce 0 ip/cgi-bin/test5-19-1.html 訪問驗證!!!tips:要想使訪問時換行顯示,要在/var/www/cgi-bin/test5-19-1.html 給這個文件加<br>然后再重啟服務!!而不是改之前的腳本文件,思路一定要清晰啊小伙子。tips:如果cp -P test5-19-1.html /var/www/html/http://192.168.4.20/test5-19-1.html訪問到的就不是腳本執行的結果了,就是html 代碼執行的結果了。如下#!/bin/bash echo "Content-type: text/html" echo "" ifconfig eth0 | awk '/netmask/{print "Ip:"$2}' echo "" ifconfig eth0 | awk '/RX p/{print "接收流量:"$5}' echo "" ifconfig eth0 | awk '/TX p/{print "發送流量:"$5}' echo "" df | awk '/\/$/{print "根分區可用:"$4}' echo "" free |awk '/Mem/{print "內存可用:"$NF}'路徑一定要是/var/www/cgi-bin/test5-19-1.html 才能訪問到腳步執行結果。(在未修改配置文件前提下)格式化輸出:awk處理的時機:處理第一行之前做準備工作 只做預處理的時候,可以沒有操作文件awk 'BEGIN{print x+1}' #x可以不定義,直接用,默認值位0中間進行逐行處理處理完最后一行做總結awk [選項] ' BEGIN{指令} {指令} END{指令}' 文件BEGIN{ } 行前處理,讀取文件內容前執行,指令執行1次{ } 逐行處理,讀取文件過程中執行,指令執行n次END{ } 行后處理,讀取文件結束后執行,指令執行1次統計系統中使用bash作為登錄Shell的用戶總個數awk 'BEGIN{x=0}/bash$/{x++} END{print x}' /etc/passwdawk '/bash$/{x++} END{print x}' /etc/passwd 與上條命令等效 x未定義默認為0格式化輸出/etc/passwd awk -F: 'BEGIN{print "User\tUID\tHome"} \{print $1 "\t" $3 "\t" $6} \ 使用“\t”顯示Tab制表位END{print "Total",NR,"lines."}' /etc/passwdawk -F: 'BEGIN{print "用戶名 家目錄 UID"} {print $1,$6,$3 x++} END{print "總共"x"行"}' /etc/passwdawk -F: 'BEGIN{print "用戶名","家目錄","UID"} {print $1,$6,$3} END{print "總共"NR"行"}' /etc/passwdawk -F: 'BEGIN{print "用戶名","家目錄","UID"} {print $1,$6,$3 x++} END{print "總用戶量:"x }' /etc/passwdEND{print "總共"NR"行"} END{print "總共"x"行"} 打印最后的時候:注意變量不要引號,常量要引號,這是個坑啊!!! awk -F: 'BEGIN{print "用戶名\t家目錄\tUID"} {print $1"\t"$6"\t"$3 x++}END{print "總用戶量:"x }' /etc/passwd | column -tcolumn -t 自動排版對齊!!!awk -F: '{print $1,$2,$3 }' /etc/passwd | column -tawk處理條件:正則awk -F: '/bash$/{print}' /etc/passwdawk -F: '$1~/(zhangsan|root)/{print $7}' /etc/passwd (支持擴展的正則)~代表匹配:$1匹配后面的正則。并且是包含就算,模糊匹配 #第一列包含root或zhangsan的打印第7列。[root@D share]# awk -F: '$1~/^root/' /etc/passwdroot:x:0:0:root:/root:/bin/bashroota:x:1004:1024::/home/roota:/bin/bash 模糊匹配awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd !~不匹配使用數值/字符串比較設置條件比較符號:== != > >= < <=awk -F: '$1=="root"' /etc/passwd 常量要引號 精確匹配用戶是為root的 不包含aroot root arootb 等等。 awk -F: 'NR==3' 打印第三行 不寫{指令}默認為打印整行(所有列)awk -F: '$3>=1000' /etc/passwd 大于等于1000的都是普通用戶。 awk -F: '$3>10 && $3<5' /etc/passwd tips:帶邏輯判斷的 要寫合理 不然的話不會報錯但是腳本執行結果不對,就不好排錯了。seq 100 | awk '$1%6!=0' 不能被6整除的。邏輯測試條件 seq 100 | awk '$1%6==0 && $1%5==0' 5和6的公倍數。seq 100 | awk '$1%7==0 || $1~/7/' 7整除或者包含7awk '/Failed/ && /invalid/' /var/log/secure 數學運算awk 'BEGIN{a++;print a}' 1 case: [root@svr5 ~]# cat getupwd-awk.sh#/bin/bashA=$(awk -F: '/bash$/{print $1}' /etc/passwd) ## 提取符合條件的賬號記錄for i in $Adogrep $i /etc/shadow | awk -F: '{print $1,"-->",$2}' doneawk 命令內部不能直接調用shell中的外部變量 $1==$i 要用-v選項來重新定義調用 很麻煩。awk流程控制(if,for,while)if判斷:單分支:if(判斷){命令} #第一個{表示命令開始 第二個}代表命令結束多分支:if(判斷){命令}else{命令} #所有指令都要放在{}里!!!!awk -F: '{if($3<=1000) {i++}} END{print i} ' /etc/passwd #結構很重要哈!!不行就先把結構框架打出來再往里面添加數據!!awk -F: '{if($3<=1000){x++}else{y++}} END{print x,y}' /etc/passwd for循環:awk數組:awk 'BEGIN{a++;print a}' 1 未定義的變量對它++就是1!!!!a=a+1 a未出現過,為空 空+1=1awk 'BEGIN{a[0]++;print a[0]}'非常重要:awk 'BEGIN{a[0]=00;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}' 0 01 112 22結果證明:i取值不是a的值而是a的下標。a[i]才是數組a的值。awk數組的下標除了可以使用數字,也可以使用字符串,字符串需要使用雙引號:awk 'BEGIN{a["192.168.4.254"]=11;print a["192.168.4.254"]}' 11awk 'BEGIN{a[192.168.4.254]=11;print a[192.168.4.254]}' 11案例: 背景:awk 統計每一個ip的訪問次數來進行過濾ls -lh /var/log/httpd/access_log 8.5kwc -l /var/log/httpd/access_log 31行ab -c 100 -n 100000 http://192.168.4.20/ dos***:模擬100人訪問了網站10萬次,這時刷新頁面就會很卡。tips:如果下標是變量就不能用引號;會把它當字符串的!先不加,結果不對了再加這樣就不會錯了.awk '{IP["$1"]++}END{for (i in IP) {print IP[i],i}}' /var/log/httpd/access_log 63445 $1awk '{IP[$1]++}END{for (i in IP) {print IP[i],i}}' /var/log/httpd/access_log |sort -n 從小到大排序219 ::163226 192.168.4.254awk腳本應用案例:
案例:快速進行源碼包安裝yum repolist | awk '/repolist/ {print $2}' |sed 's/,//g'源碼包裝的軟件不能用systemctl restart (enable) 來進行管理。netstat -ntulp |grep httpdtcp6 0 0 :::80 :::* LISTEN 8002/httpdnetstat -ntulp |grep :80 tcp6 0 0 :::80 :::* LISTEN 8002/httpdnetstat -ntulp |grep :80[ $? -ne 0 ] && /usr/local/nginx/sbin/nginxa=$(netstat -ntulp |awk '/:80/{print $7}'|cut -d/ -f2)[ $a == "httpd" ] && systemctl stop $a b=(netstat -ntulp |awk '/:80/{print $7}'|cut -d/ -f2|cut -d: -f1)啟動腳本niginx(case)看本機狀態信息uptime |awk '{print$9,$10,$11}ifconfig eth0 | awk '/RX p/{print $5}'ifconfig eth0 | awk '/TX p/{print $5}'free |awk '/Mem/{print $NF}'df | awk '/\/$/{print $4}'cat /etc/passwd |wc -lwho |wc -lrpm -qa |wc -l$!最后一個后臺進程的進程號。 防止遠程ssh暴力破解密碼awk '/Failed/ && /invalid/{print $13}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'awk '/Failed/ && $9!~/invalid/{print $11}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'1 #!/bin/bash2 a=$(awk '/Failed/ && $9!~/invalid/{print $11}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'|awk '{if($2>5){print$1}}')3 4 b=$(awk '/Failed/ && $9!~/invalid/{print $11}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'|awk '{if($2>5){print$1}}')5 echo $a6 echo $b轉載于:https://blog.51cto.com/13659481/2120840
總結
以上是生活随笔為你收集整理的Linux阶段总结shell脚本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解并使用python的模块与包
- 下一篇: 使用Google、百度等搜索引擎完全匹配