6一、題目要求 : 找文件差別php
有兩個文件a.txt中和b.txt,需求是,把A.TXT中有的但b.txt中沒有的行找出來,並寫入到c.txt,而後計算c.txt文件的行數。html
【核心要點】python
可使用while循環遍歷a.txt,逐行進行匹配,若是這一行在b.txt中沒有,就直接重定向到c.txt便可mysql
參考答案linux
#!/bin/bash #這個腳本用來比較文件差別 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-07 cat a.txt|while read line do if ! grep -q "$line" b.txt then echo $line fi done >c.txt wc -l c.txt
實例 :git
編寫a.txt 和b.txt文檔,用於測試github
比較b.txt文檔,使用 -f命令,把匹配到的關鍵詞root用紅色顯示出來。 web
找出a.txt 和b.txt文檔共同存在的關鍵詞sql
找出a.txt 有,b.txt中文檔不存在的關鍵詞shell
把a.txt 和b.txt文檔不一樣的關鍵詞,顯示出來。
執行腳本,查看運行的結果。3表示有3行不一樣的。
注意 :
if ! grep -q "$line" b.txt #b.txt文檔中的沒有的,
done >c.txt #把a.txt 和b.txt文檔不一樣的關鍵詞寫入到c.txt文檔中 wc -l c.txt #統計一下,c.txt 中的行數
6二、題目要求 : 殺進程
把當前用戶下全部進程名字中含有 「阿明」 的進程關閉。
【核心要點】
ps -u $USER
#!/bin/bash #這個腳本用來殺進程 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-07 ps -u $USER|awk '$NF ~ /aming/ {print $1}' |xargs kill
實例 :
查看當前的用戶
查看指定的用戶
查看當前用戶下的進程數
查看當前用戶下的進程數,最後一行匹配「aming」的用戶
查看出kworke用戶的行;並打印出第一行;查找aming用戶,並打印出第一行,殺死aming用戶。
執行腳本,查看運行的結果。
注意 :
ps -u $USER|awk '$NF ~ /aming/ {print $1}' |xargs kill
6三、題目要求 : 併發備份數據庫
用外殼實現,以併發進程的形式將MySQL的數據庫全部的表備份到當前目錄,並把全部的表壓縮到一個壓縮包文件裏。
假設數據庫名字爲MYDB,用戶名爲阿明,密碼爲passwd文件。
【核心要點】
一、在shell中加上&能夠將命令丟到後臺,從而能夠同時執行多條命令達到併發的效果
二、若是表數量很大,所有都丟到後臺去,服務資源恐怕支持不了,因此須要控制併發數。
三、備份表的命令是mysqldump -uaming -ppasswd mydb tbname > tbname.sql
#!/bin/bash #這個腳本用來併發備份數據庫 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-07 N=5 mysql -uaming -ppasswd mydb -e "show tables"|sed '1d' > /tmp/table.txt n=`wc -l /tmp/table.txt|awk '{print $1}' div() { n=`echo "scale=1;$1/$2"|bc` n1=`echo "scale=1;$n+0.5"|bc` echo $n1|cut -d. -f1 } n1=`div $n $N` split -l $n1 /tmp/table.txt myd() { for t in `cat $1` do mysqldump -uaming -ppasswd mydb $t > $t.sql done } for f in xaa xab xac xad xae do myd $f & done wait tar czf mydb.tar.gz *.sql rm -f *.sql
實例 :
把test.txt文檔分爲4份,使用split命令,分割,ls查看分割結果;爲什麼只有三個結果,由於是四捨五入的,x開頭的文件指的是併發數。
split命令能夠指定分割以後,生成的文件名test
注意 :
$1 #是文件名
N=5 #N=5表示併發分爲5份
mysql -uaming -ppasswd mydb -e "show tables"|sed '1d' > /tmp/table.txt n=`wc -l /tmp/table.txt|awk '{print $1}' #mydb數據庫顯示全部的列表,刪除第一行,表的列表寫入/tmp/table.txt 文件中
`wc -l /tmp/table.txt|awk '{print $1}' #計算文件的行數,並打印出來第一行
for f in xaa xab xac xad xae #表示併發產生的5個表
myd $f & #&表示把進程丟到後臺去
mysqldump -uaming -ppasswd mydb $t > $t.sql #備份數據庫,$t是表名,寫入到當前目錄的數據庫$t.sql
n1=`div $n $N` #$n除以$N ; $n是除數 $N是被除數
求一個平均值
n=`echo "scale=1;$1/$2"|bc` #
n1=`echo "scale=1;$n+0.5"|bc` #
echo $n1|cut -d. -f1 #
tar czf mydb.tar.gz *.sql #把全部的數據庫打包成壓縮包
split -l $n1 /tmp/table.txt
#把/tmp/table.txt
文件分爲$n1份
;-l意思是指要切割的行數
6四、題目要求 : 監控CDN節點
一個網站,使用了cdn,全國各地有幾十個節點。須要你寫一個shell腳原本監控各個節點是否正常。假如
【核心要點】
一、某個節點正常,那訪問到的內容應該和源
二、比較兩個文件內容是否有差別的命令爲diff,如,diff 1.txt 2.txt若是結果爲空,說明兩個文件不存在差別
三、幾十個節點,須要把全部節點的IP所有拿到,而後對全部IP進行遍歷
#!/bin/bash #這個腳本用來監控CDN節點 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-08 s_ip=88.88.88.88 url=www.aminglinux.com/index.php ipf=/data/ip.list curl -x$s_ip:80 $url 2>/dev/null >/tmp/source.txt for ip in `cat $ipf` do curl -x$ip:80 $url 2>/dev/null >/tmp/$ip.txt diff /tmp/source.txt /tmp/$ip.txt > /tmp/$ip.diff n=`wc -l /tmp/$ip.diff|awk '{print $1}'` if [ $n -gt 0 ] then echo "節點$ip有異常." fi done
實例 :
把index.php頁面,重定向到/tmp/tmp.txt文件中去
直接寫入到/tmp/tmp.txt文件中去,不顯示過程結果。
注意 :
curl -x$s_ip:80 $url 2>/dev/null >/tmp/source.txt #訪問節點IP,並把訪問的結果寫入到/tmp/source.txt ,不顯示重定向過程; -x指定IP
for ip in `cat $ipf` #將IP寫入到$ipf
diff /tmp/source.txt /tmp/$ip.txt > /tmp/$ip.diff #/tmp/source.txt比對/tmp/$ip.txt 這兩個文件的差別,若是有,說明出問題了,並將結果寫入到/tmp/$ip.diff
wc -l /tmp/$ip.diff|awk '{print $1}' #將比對出來的結果,統計一下行數,只顯示一行。
if [ $n -gt 0 ] #若是gt的結果是0,說明出問題了
6五、題目要求 : 破解字符串
已知下面的字符串是經過RANDOM隨機數變量md5sum | cut -c 1-8截取後的結果,請破解這些字符串對應的md5sum前的RANDOM對應數字?21029299
00205d1c
a3da1677
1f6d12dd
890684ba
$RAMDOM的範圍爲0-32767,要想借此題,須要遍歷0-32767全部數字,逐一和題目中給出的字符串匹配
#!/bin/bash #這個腳本用來破解字符串 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-08 for i in `seq 0 32767` do m=`echo $i|md5sum |cut -c 1-8 ` echo $i $m done > /tmp/md5.txt cat > c.txt <<EOF 21029299 00205d1c a3da1677 1f6d12dd 890684ba EOF grep -f c.txt /tmp/md5.txt
實例 :
求12345的md5sum的值,並截取前1-8的數字
執行腳本,查看結果,由於要計算3萬多數字,因此須要很長時間等待腳本的執行結果。
注意 :
for i in `seq 0 32767` #求出0-32767之間的md5sum的值
m=`echo $i|md5sum |cut -c 1-8 ` #
求$i的md5sum的值,並截取前1-8的數字
grep -f c.txt /tmp/md5.txt #
cat > c.txt <<EOF #將全部的數字寫入到c.txt文檔中
6六、題目要求 : 判斷cpu廠商
寫一個腳本:
【核心要點】
一、截取/proc/cpuinfo文檔包含「vendor_id」那行的文本
#!/bin/bash #這個腳本用來判斷CPU廠商 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-10 cpu=`grep '^vendor_id' /proc/cpuinfo |head -1|awk -F ': ' '{print $2}'` #if [ $cpu == "AuthenticAMD" ] #then # echo "CPU廠商是AMD." #elif [ $cpu == "GenuineIntel" ] #then # echo "CPU廠商是Intel." #else # echo "CPU廠商是非主流廠商。" #fi case $cpu in AuthenticAMD) echo "CPU廠商是AMD." ;; GenuineIntel) echo "CPU廠商是Intel." ;; *) echo "CPU廠商是非主流廠商。" ;; esac
實例 :
查看cpu廠商的命令 : cat /proc/cpuinfo , 顯示其爲英特爾公司;
截取含有「vendor_id」的行,在/proc/cpuinfo中,head -1只顯示第一行
由於廠商名字在第二行,因此用{print $2},只截取廠商的名字,
注意 : ntpdate命令聯網同步時間,緣由 : linux長期不登陸,時間可能和windows系統不一樣步。
執行腳本,查看結果
注意 :
cpu=`grep '^vendor_id' /proc/cpuinfo |head -1|awk -F ': ' '{print $2}'` #查找含有vendor_id ,在/proc/cpuinfo中查看,只顯示第一行,把含有廠商的第二行打印處理,
elif [ $cpu == "GenuineIntel" ] #若是是CPU是GenuineIntel
6七、題目要求 : 監控CPU使用率
用殼寫一個監控服務器CPU使用率的監控腳本。
【核心要點】
思路 : 用top -bn1 命令,取當前空閒cpu百分比值(只取整數部分),而後用100去減這個數值
#!/bin/bash #這個腳本用來計算CPU使用率 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-10 mail_user=xxx@xxx.com m_mail() { log=$1 t_s=`date +%s` t_s2=`date -d "1 hours ago" +%s` if [ ! -f /tmp/$log ] then #建立$log文件 touch /tmp/$log #增長a權限,只容許追加內容,不容許更改或刪除 chattr +a /tmp/$log #第一次告警,能夠直接寫入1小時之前的時間戳 echo $t_s2 >> /tmp/$log fi #不管$log文件是不是剛剛建立,都須要查看最後一行的時間戳 t_s2=`tail -1 /tmp/$log|awk '{print $1}'` #取出最後一行即上次告警的時間戳後,當即寫入當前的時間戳 echo $t_s>>/tmp/$log #取兩次時間戳差值 v=$[$t_s-$t_s2] #若是差值超過1800,當即發郵件 if [ $v -gt 1800 ] then #發郵件,其中$2爲mail函數的第二個參數,這裏爲一個文件 python mail.py $mail_user "CPU使用率超過90%" "`top -bn1`" 2>/dev/null #定義計數器臨時文件,並寫入0 echo "0" > /tmp/$log.count else #若是計數器臨時文件不存在,須要建立並寫入0 if [ ! -f /tmp/$log.count ] then echo "0" > /tmp/$log.count fi nu=`cat /tmp/$log.count` #30分鐘內每發生1次告警,計數器加1 nu2=$[$nu+1] echo $nu2>/tmp/$log.count #當告警次數超過30次,須要再次發郵件 if [ $nu2 -gt 30 ] then python mail.py $mail_user "CPU使用率超過90%持續30分鐘了" "`top -bn1`" 2>/dev/null #第二次告警後,將計數器再次從0開始 echo "0" > /tmp/$log.count fi fi } while : do cpu_i=`top -bn1 |grep 'Cpu(s):'|sed 's/^%//'|awk -F ' +|%' '{print $8}'` cpu_u=`echo 100-$cpu_i|bc` if [ $cpu_u -gt 90 ] then m_mail cpu fi sleep 60 done
實例 :
使用top命令查看你,第三行就是cpu使用率;us是用戶態的服務CPU使用率,sy是系統態的CPU使用率。日常的使用率是指us和sy的使用率。使用率等於100-id(99.3)
centos 7靜態顯示CPU使用率,顯示使用率是100-99.2。centOS 6的id後面有百分號%
只顯示出來,含有CPU的行。按空格作分隔符,含有CPU的在第五行
用百分號%作分隔符,含有CPU的在第八行用空格加,表示一個或者多個空格
sed清空第一個%,而後在centos 7 執行這個命令。
執行腳本,查看結果。
只查看CPU的使用率的腳本
注意 :
t_s=`date +%s` #
t_s2=`date -d "1 hours ago" +%s` #
if [ $cpu_u -gt 90 ] #當使用率大於90時,每隔1分鐘發一封郵件
6八、題目要求 : 打印子進程
給出一個進程PID,打印出該進程下面的子進程以及子進程下面的全部子進程。(只須要考慮子進程的子進程,再往深層次則不考慮)
ps -elf結果中PPID那一列爲父進程PID
#!/bin/bash #這個腳本用來打印子進程 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-10 ps -elf > /tmp/pid.txt read -p "Please input a pid: " p if [ -z "$p" ] then echo "你沒有輸入任何pid,請輸入一個pid." exit fi if ! grep -qw "$p" /tmp/pid.txt then echo "你輸入的pid不存在." exit fi get_cpid() { p1=$1 ps -elf |awk -v p2=$p1 '$5==p2 {print $4}' > /tmp/$p1.txt n=`wc -l /tmp/$p1.txt|awk '{print $1}'` if [ $n -eq 0 ] then echo "進程$1下沒有子進程." else echo "進程$1下的子進程是:" cat /tmp/$p1.txt fi } get_cpid $p for c_p in `cat /tmp/$p.txt` do get_cpid $c_p done
實例 :
查看進程的pid,ppid是父進程
一用進程樹的方式顯示進程
只顯示ppid的進程數字
查看進程ppid對應的pid子進程數字
執行腳本,查看結果
注意 :
ps -elf > /tmp/pid.txt # 把進程的pid寫入到/tmp/pid.txt
if [ -z "$p" ] #輸入的變量爲空
if ! grep -qw "$p" /tmp/pid.txt #若是/tmp/pid.txt 中不包含輸入的pid,就提醒「你輸入的pid不存在.」
wc -l /tmp/$p1.txt|awk '{print $1}' #統計行數,並只打印出顯示出來的第一行。
6九、題目要求 : 給lamp環境增長項目
需求背景:服務器上,跑的燈環境,上面有不少客戶的項目,每一個項目就是一個網站。因爲客戶在不斷增長,每次增長一個客戶,就須要配置相應的mysql,ftp以及httpd。這種工做重複性很是強的,因此用腳本實現很是合適.mysql增長的是對應客戶項目的數據庫,用戶,密碼,FTP增長的是對應項目的用戶,密碼(使用vsftpd的,虛擬用戶模式),httpd的就是要增長虛擬主機配置段。
要想解此題,首先要搞清楚MySQL庫和用戶,增長httpd虛擬主機、增長FTP用戶的命令,只要能在命令行搞定,那麼在腳本中就沒問題。
#!/bin/bash #本腳本的功能是在LAMP環境中增長站點,包括apache配置、FTP增長用戶、MySQL增長庫和用戶 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-10 #網站目錄 webdir=/data/wwwroot #ftp的虛擬用戶配置文件目錄 ftpudir=/etc/vsftpd/vuuser #ftp虛擬用戶密碼文件 ftpuserfile=/root/login #mysql命令行登陸root mysqlc="/usr/local/mysql/bin/mysql -uroot -pjk1hYUcnt6" #apache虛擬主機配置文件 httpd_config_f="/usr/local/apache2/conf/extra/httpd-vhosts.conf" #定義增長MySQL庫和用戶的函數 add_mysql_user() { #生成隨機密碼 mysql_p=`mkpasswd -s 0 -l 12` #將密碼保存到臨時文件裏,這裏的$pro爲用戶自定義的項目名字 echo "$pro $mysql_p" >/tmp/$pro.txt #這裏使用嵌入文檔的形式(需頂格),將建立用戶並受權的命令傳遞給mysql $mysqlc <<EOF create database $pro; grant all on $pro.* to "$pro"@'127.0.0.1' identified by "$mysql_p"; #下面這個EOF必需要頂格 EOF } #定義增長FTP用戶的函數 add_ftp_user() { ftp_p=`mkpasswd -s 0 -l 12` echo "$pro" >> $ftpuserfile echo "$ftp_p" >> $ftpuserfile #將用戶、密碼文件轉換爲密碼db文件 db_load -T -t hash -f $ftpuserfile /etc/vsftpd/vsftpd_login.db cd $ftpudir #這裏的aaa是一個文件,是以前的一個項目,能夠做爲配置模板 cp aaa $pro #把裏面的aaa改成新的項目名字 sed -i "s/aaa/$pro/" $pro #重啓vsftpd服務 /etc/init.d/vsftpd restart } #定義增長apache虛擬主機的函數 config_httpd() { #增長網站根目錄,和域名保持一致,這裏的$dom爲用戶自定義的域名 mkdir $webdir/$dom #將網站根目錄屬主和屬組設置爲ftp用戶 chown vsftpd:vsftpd $webdir/$dom #用嵌入文檔(需頂格),把虛擬主機配置寫入到配置文件裏 cat >> $httpd_config_f <<EOF <VirtualHost *:80> DocumentRoot $webdir/$dom ServerName $dom <Directory $webdir/$dom> AllowOverride none Require all granted </Directory> </VirtualHost> EOF #重載apache服務 /usr/local/apache2/bin/apachectl graceful } read -p "input the project name: " pro read -p "input the domain: " dom add_mysql_user add_ftp_user config_httpd
實例 :
執行腳本,查看結果
注意 :
$ftpuserfile #用戶的密碼文件
create database $pro; #建立數據庫$pro
grant all on $pro.* to "$pro"@'127.0.0.1' identified by "$mysql_p"; #賦予數據庫密碼
70、題目要求 : 簡易計算器
用shell寫一個簡易計算器,能夠實現加,減,乘,除運算,假如腳本名字爲1.sh,執行示例:./ 1.sh 1 + 2
一、腳本有三個參數,因此第一要判斷用戶輸入的參數個數是否符合要求。
二、第一個第三個參數是數字,能夠是小數,但不能是負數,第二個參數只能是+、-、*、/、,若是是其餘要報錯。
#!/bin/bash #這個腳本用來實現簡易計算器 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-10 if [ $# -ne 3 ] then echo "你給的參數個數不對,應該給3個參數." exit fi if_number() { n1=`echo $1|sed 's/[0-9.]//g'` if [ -n "$n1" ] then echo "$1不是數字." exit fi if echo $1|grep -q '^\.' then echo "數字$1不合法." exit fi } if_number $1 if_number $3 case $2 in +) echo "$1+$3"|bc ;; -) echo "$1-$3"|bc ;; \*) echo "$1*$3"|bc ;; /) echo "scale=2;$1/$3"|bc ;; *) echo "你給出的格式不對,第二個參數只能是+,-,*,/" ;; esac
實例 :
執行腳本,查看結果. 1除以3,保留兩位數
注意 :
if [ $# -ne 3 ] #$#不等於3,提示 「你給的參數個數不對,應該給3個參數.」
n1=`echo $1|sed 's/[0-9.]//g'` # 若是輸入的數字不是數字,是空的
if [ -n "$n1" ] #若是不爲空,提示「$1不是數字.」 退出
if echo $1|grep -q '^\.'
#若是有以點開頭的,提示"數字$1不合法.
"
echo "$1+$3"|bc #$1+$3的值,比較大小
echo "scale=2;$1/$3"|bc #保留兩位小數,$1除以$3
來源 :https://github.com/aminglinux/shell100/blob/master/13.md