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