描述:請按照這樣的日期格式(xxxx-xx-xx)每日生成一個文件,例現在天生成的文件爲)2017-07-05.log, 而且把磁盤的使用狀況寫到到這個文件中,(不用考慮cron,僅僅寫腳本便可)php
參考答案html
d=`date +%F` logfile=$d.log file_path='/data/shell/log/'$logfile df -h >$file_path
注:1)date +%F中date與+之間存在空格node
2)其餘建立路徑/data/shell/logpython
描述: 將下述日誌屢次複製粘貼至02.log中,編寫腳本,統計出每一個IP的訪問量有多少?mysql
112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com 「/seccode.php?update=0.5593110133088248″ 200″http://formula-x.haotui.com/registerbbs.php」 「Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)」linux
61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com 「/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301″http://xyzdiy.5d6d.com/thread-1435-1-23.html」 「Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)」nginx
參考答案:git
awk ‘{print $1}’ 1.log |sort -n|uniq -c |sort -nweb
描述:寫一個腳本計算一下linux系統全部進程佔用內存大小的和。(提示,使用ps或者top命令)sql
上述字段說明:
USER 進程的屬主;
PID 進程的ID;
PPID 父進程;
%CPU 進程佔用的CPU百分比;
%MEM 佔用內存的百分比;
NI 進程的NICE值,數值大,表示較少佔用CPU時間;
VSZ 該進程使用的虛擬內存量(KB);
RSS 該進程佔用的固定內存量(KB)(駐留中頁的數量);
TTY 該進程在那個終端上運行(登陸者的終端位置),若與終端無關,則顯示(?)。若為pts/0等,則表示由網絡連接主機進程
WCHAN 當前進程是否正在進行,若為-表示正在進行;
START 該進程被觸發啓動時間;
TIME 該進程實際使用CPU運行的時間;
COMMAND 命令的名稱和參數;
參考答案:
#! /bin/bash sum=0 for i in `ps aux|awk '{print $6}'|grep -v RSS` do sum=$[$sum+$i] echo $i done echo "The total memory is $sum""k"
描述:
設計一個腳本,監控遠程的一臺機器(假設ip爲123.23.11.21)的存活狀態,當發現宕機時發一封郵件給你本身。
提示:
1. 你可使用ping命令 ping -c10 123.23.11.21
2. 發郵件腳本能夠參考 https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
3. 腳本能夠搞成死循環,每隔30s檢測一次
#!/bin/bash ip=10.1.1.1 ma=xxxx@qq.boe.com.cn while ((1)) do ping -c10 $ip >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then python /data/python/mail.py $ma "$ip is down" "$ip is down" fi sleep 1 done
注:while ((1))等同於while [ 1 ]等同於 while true
#!/usr/bin/env python #-*- coding: UTF-8 -*- import os,sys reload(sys) sys.setdefaultencoding('utf8') import getopt import smtplib from email.MIMEText import MIMEText from email.MIMEMultipart import MIMEMultipart from subprocess import * def sendqqmail(username,password,mailfrom,mailto,subject,content): gserver = 'smtp.qq.com' gport = 25 try: # msg = MIMEText(unicode(content).encode('utf-8')) //若是發送的郵件有亂碼,能夠嘗試把這行改爲以下: msg = MIMEText(content,'plan','utf-8') msg['from'] = mailfrom msg['to'] = mailto msg['Reply-To'] = mailfrom msg['Subject'] = subject smtp = smtplib.SMTP(gserver, gport) smtp.set_debuglevel(0) smtp.ehlo() smtp.login(username,password) smtp.sendmail(mailfrom, mailto.split(','), msg.as_string()) smtp.close() except Exception,err: print "Send mail failed. Error: %s" % err def main(): to=sys.argv[1] subject=sys.argv[2] content=sys.argv[3] ##定義QQ郵箱的帳號和密碼,你須要修改爲你本身的帳號和密碼(請不要把真實的用戶名和密碼放到網上公開,不然你會死的很慘) sendqqmail('1234567@qq.com','aaaaaaaaaa','1234567@qq.com',to,subject,content) if __name__ == "__main__": main() #####腳本使用說明###### #1. 首先定義好腳本中的郵箱帳號和密碼 #2. 腳本執行命令爲:python mail.py 目標郵箱 "郵件主題" "郵件內容"
描述:
參考答案
#!/bin/bash #查找txt文件 find /data/shell/123 -type f -name "*.txt" >/tmp/txt.list #批量修改文件名 for f in `cat /tmp/txt.list` do mv $f $f.bak done #建立一個目錄,避免目錄存在,因此加了一個時間的後綴名 d=`date +%Y%m%d%H%M%S` mkdir /tmp/123_$d pwd for f in `cat /tmp/txt.list` do echo "true" cp $f.bak /tmp/123_$d/ done #打包壓縮 cd /tmp tar czf 123.tar.gz 123_$d/ #還原 for f in `cat /tmp/txt.list` do mv $f.bak $f done
描述:
寫一個腳本,判斷本機的80端口(假如服務爲httpd)是否開啓着,若是開啓着什麼都不作,若是發現端口不存在,那麼重啓一下httpd服務,併發郵件通知你本身。腳本寫好後,能夠每一分鐘執行一次,也能夠寫一個死循環的腳本,30s檢測一次。
#! /bin/bash mail=123@123.com if netstat -lnp |grep ‘:80’ |grep -q ‘LISTEN’; then exit else /usr/local/apache2/bin/apachectl restart >/dev/null 2> /dev/null python mail.py $mail 「check_80」 「The 80 port is down.」 n=`ps aux |grep httpd|grep -cv grep` if [ $n -eq 0 ]; then /usr/local/apache2/bin/apachectl start 2>/tmp/apache_start.err fi if [ -s /tmp/apache_start.err ]; then python mail.py $mail ‘apache_start_error’ `cat /tmp/apache_start.err` fi fi
相關知識:
1)文件目錄判斷 [ -s FILE ] 若是 FILE 存在且大小非0時爲真則返回爲真。
https://blog.csdn.net/jasonzeng/article/details/53286384
2)netstat
常見參數:命令用於顯示各類網絡相關信息,如網絡鏈接,路由表,接口狀態 (Interface Statistics),masquerade 鏈接,多播成員 (Multicast Memberships) 等等。
-a (all)顯示全部選項,默認不顯示LISTEN相關
-t (tcp)僅顯示tcp相關選項
-u (udp)僅顯示udp相關選項
-n 拒絕顯示別名,能顯示數字的所有轉化成數字。
-l 僅列出有在 Listen (監聽) 的服務狀態
-p 顯示創建相關連接的程序名
-r 顯示路由信息,路由表
-e 顯示擴展信息,例如uid等
-s 按各個協議進行統計
-c 每隔一個固定時間,執行該netstat命令。
https://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316661.html
3)grep -q
-q 參數,本意是 Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected. 中文意思爲,安靜模式,不打印任何標準輸出。若是有匹配的內容則當即返回狀態值0。
描述:
設計一個shell腳原本備份數據庫,首先在本地服務器上保存一份數據,而後再遠程拷貝一份,本地保存一週的數據,遠程保存一個月。
假定,咱們知道mysql root帳號的密碼,要備份的庫爲discuz,本地備份目錄爲/bak/mysql, 遠程服務器ip爲192.168.123.30,遠程提供了一個rsync服務,備份的地址是 192.168.123.30::backup . 寫完腳本後,須要加入到cron中,天天凌晨3點執行。
#! /bin/bash ### backup mysql data ### Writen by Aming. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/mysql/bin d1=`data +%w` d2=`date +%d` pass=」your_mysql_password」 bakdir=/bak/mysql r_bakdir=192.168.123.30::backup exec 1>/var/log/mysqlbak.log 2>/var/log/mysqlbak.log echo 「mysql backup begin at `date +」%F %T」`.」 mysqldump -uroot -p$pass –default-character-set=gbk discuz >$bakdir/$d1.sql rsync -az $bakdir/$d1.sql $r_bakdir/$d2.sql echo 「mysql backup end at `date +」%F %T」`.」
而後加入cron
0 3 * * * /bin/bash /usr/local/sbin/mysqlbak.sh
描述:
服務器上跑的是LNMP環境,近期老是有502現象。502爲網站訪問的狀態碼,200正常,502錯誤是nginx最爲普通的錯誤狀態碼。因爲502只是暫時的,而且只要一重啓php-fpm服務則502消失,但不重啓的話,則會一直持續很長時間。因此有必要寫一個監控腳本,監控訪問日誌的狀態碼,一旦發生502,則自動重啓一下php-fpm。
咱們設定:
1. access_log /data/log/access.log
2. 腳本死循環,每10s檢測一次(假設每10s鐘的日誌條數爲300左右)
3. 重啓php-fpm的方法是 /etc/init.d/php-fpm restart
參考答案
#! /bin/bash log=/data/log/access.log N=10 while :; do ##由於10秒鐘大概產生300條日誌 tail -n 300 $log > /tmp/log n_502=`grep -c ‘ 502″‘ /tmp/log` if [ $n_502 -ge $N ]; then ##記錄系統的狀態 top -bn1 >/tmp/`date +%H%M%S`-top.log vmstat 1 5 >/tmp/`date +%H%M%S`-vm.log /etc/init.d/php-fpm restart 2>/dev/null ##重啓php-fpm服務後,應先暫緩1分鐘,然後繼續每隔10s檢測一次 sleep 60 fi sleep 10 done
描述:
把一個文本文檔的前5行中包含字母的行刪除掉,同時把6到10行中的所有字母刪除掉。
參考答案
假設文本名字叫作1.txt,而且文本行數大於10,腳本以下
#!/bin/bash ##先獲取該文本的行數 nu=`wc -l 1.txt |awk '{print $1}'` ##對前5行進程處理 for i in `seq 1 5` do ##使用sed把每一行的內容賦值給變量 l=`sed -n "$ip" 1.txt` ##用grep 斷定是否匹配字母,-v取反,-q不輸出內容 if echo $l |grep -vq '[a-zA-Z]' then echo $l fi done ##對6-10行作刪除字母處理 for i in `seq 6 10` do l=`sed -n "$i"p 1.txt` echo $l|sed 's/[a-zA-Z]//g' done ##剩餘的直接輸出 for i in `seq 11 $nu` do sed -n "$i"p 1.txt done ##若想把更改內容寫入到1.txt,還須要把以上內容重定向到一個文本中,而後刪除1.txt,再把剛剛重定向的文件>改名爲1.txt
描述:
用shell打印下面這句話中字母數小於6的單詞。
Bash also interprets a number of multi-character options.
參考答案
#!/bin/bash for s in Bash also interprets a number of multi-character options do n=`echo $s|wc -c` if [ $n -lt 6 ] then echo $s fi done
描述:
寫一個腳本實現以下功能: 輸入一個數字,而後運行對應的一個命令。
顯示命令以下:*cmd meau** 1—date 2–ls 3–who 4–pwd
當輸入1時,會運行date, 輸入2時運行ls, 依此類推。
參考答案
#!/bin/bash echo "**cmd meau** 1-date 2-ls 3-who 4-pwd" read -p "Please input a number 1-4:" n echo $n case $n in 1) date ;; 2) ls ;; 3) who ;; 4) pwd ;; *) echo "Please input a number:1-4" ;; esac
描述:
添加user_00 – user_09 10個用戶,而且給他們設置一個隨機密碼,密碼要求10位包含大小寫字母以及數字,注意須要把每一個用戶的密碼記錄到一個日誌文件裏。
提示:
1. 隨機密碼使用命令 mkpasswd
2. 在腳本中給用戶設置密碼,可使用echo 而後管道passwd命令
#!/bin/bash for i in `seq -w 00 09` do useradd user_$i #隨機生成10位不包含特殊符號的密碼 p=`mkpasswd -s 0 -l 10` echo "$p" echo "user_$i $p" >>/tmp/user0_9.pass #修改指定用戶的密碼 echo $p|passwd --stdin user_$i done
注:1)mkpasswd的命令執行的前提是安裝了expect,如果沒有安裝可執行yum install expect 進行安裝
usage: mkpasswd [args] [user]
參數:
-l # (密碼的長度定義, 默認是 9)
-d # (數字個數, 默認是 2)
-c # (小寫字符個數, 默認是 2)
-C # (大寫字符個數, 默認是 2)
-s # (特殊字符個數, 默認是 1)
-v (詳細。。。)
-p prog (程序設置密碼, 默認是 passwd)
描述:
在服務器上,寫一個監控腳本。
1. 每隔10s去檢測一次服務器上的httpd進程數,若是大於等於500的時候,就須要自動重啓一下apache服務,並檢測啓動是否成功?
2. 若沒有正常啓動還需再一次啓動,最大不成功數超過5次則須要理解發郵件通知管理員,而且之後不須要再檢測!
3. 若是啓動成功後,1分鐘後再次檢測httpd進程數,若正常則重複以前操做(每隔10s檢測一次),若仍是大於等於500,那放棄重啓並須要發郵件給管理員,而後自動退出該腳本。假設其中發郵件腳本爲以前我們使用的mail.py
參考答案
#!/bin/bash check_service() { n=0 for i in `seq 1 5` do /usr/local/apache2/bin/apachectl restart 2>/tmp/apache.err if [ $? -ne 0 ] then n=$[$n+1] else break fi done if [ $n -eq 5 ] then ##下面的mail.py參考https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py python mai.py "123@qq.com" "httpd service down" `cat /tmp/apache.err` exit fi } while : do t_n=`ps -C httpd --no-heading |wc -l` if [ $t_n -ge 500 ] then /usr/local/apache2/bin/apachectl restart if [ $? -ne 0 ] then check_service fi sleep 60 t_n=`ps -C httpd --no-heading |wc -l` if [ $t_n -ge 500 ] then python mai.py "123@qq.com" "httpd service somth wrong" "the httpd process is budy." exit fi fi sleep 10 done
描述:根據web服務器上的訪問日誌,把一些請求量很是高的ip給拒絕掉!
分析: 咱們要作的,不只是要找到哪些ip請求量不合法,而且還要每隔一段時間把以前封掉的ip(若再也不繼續請求了)給解封。 因此該腳本的關鍵點在於定一個合適的時間段和閾值。
好比, 咱們能夠每一分鐘去查看一下日誌,把上一分鐘的日誌給過濾出來分析,而且只要請求的ip數量超過100次那麼就直接封掉。 而解封的時間又規定爲每半小時分析一次,把幾乎沒有請求量的ip給解封!
參考日誌文件片斷:
157.55.39.107 [20/Mar/2015:00:01:24 +0800] www.aminglinux.com 「/bbs/thread-5622-3-1.html」 200 「-」 「Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)」
61.240.150.37 [20/Mar/2015:00:01:34 +0800] www.aminglinux.com 「/bbs/search.php?mod=forum&srchtxt=LNMP&formhash=8f0c7da9&searchsubmit=true&source=hotsearch」 200 「-」 「Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)」
參考答案
#! /bin/bashlogfile=/home/logs/client/access.log d1=`date -d "-1 minute" +%H:%M` d2=`date +%M` ipt=/sbin/iptables ips=/tmp/ips.txt block(){ grep "$d1:" $logfile|awk '{print $1}' |sort -n |uniq -c |sort -n >$ips for ip in `awk '$1>50 {print $2}' $ips`; do $ipt -I INPUT -p tcp --dport 80 -s $ip -j REJECT echo "`date +%F-%T` $ip" >> /tmp/badip.txt done } unblock(){ for i in `$ipt -nvL --line-numbers |grep '0.0.0.0/0'|awk '$2<15 {print $1}'|sort -nr`; do $ipt -D INPUT $i done $ipt -Z } if [ $d2 == "00" ] || [ $d2 == "30" ]; then unblock block else block fi
請詳細查看以下幾個數字的規律,並使用shell腳本輸出後面的十個數字。
10 31 53 77 105 141 …….
試題解析:
我想大多數人都會去比較這些數字的差值:
10 31 53 77 105 141
21 22 24 28 36
可是這個差值看,並無什麼規律,而咱們再仔細看的時候,發現這個差值的差值是有規律的:
10 31 53 77 105 141
21 22 24 28 36
1 2 4 8
參考答案:
#!/bin/bash x=21 m=10 echo $m for i in `seq 0 14`; do j=$[2**$i] m=$[$m+$x] echo $m x=$[$x+$j] done
描述:寫個shell,看看你的Linux系統中是否有自定義用戶(普通用戶),如果有,一共有幾個?
參考答案:
假設全部普通用戶都是uid大於1000的
#!/bin/bash n=`awk -F ':' '$3>1000' /etc/passwd|wc -l` if [ $n -gt 0 ] then echo "There are $n common users." else echo "No common users." fi
不太理解爲甚麼uid大於1000的都是普通用戶
寫一個shell腳本,檢測全部磁盤分區使用率和inode使用率並記錄到以當天日期爲命名的日誌文件裏,當發現某個分區容量或者inode使用量大於85%時,發郵件通知你本身。
思路:就是先df -h 而後過濾出已使用的那一列,而後再想辦法過濾出百分比的整數部分,而後和85去比較,同理,inode也是同樣的思路
參考答案:
#!/bin/bash log=/tmp/log/`date +%F`.log date +'%F %T' df -h >>$log echo >>$log df -i >>$log ma=xxx@123.com for i in `df -h|grep -v 'Use%'|sed 's/%//'|awk '{print $5}'`;do if [ $i -gt 85 ];then use=`df -h|grep -v 'Use%'|sed 's/%//'|awk '$5=='$i' {print $1,$5}'` echo "$use" >>sue fi done if [ -e use ]; then python /data/python/mail.py $ma "Filesystem Use% > 85%" "$use" fi for j in `df -i|grep -v 'IUse%'|sed 's/%//'|awk '{print $5}'`;do if [ $j -gt 85 ]; then iuse=`df -i|grep -v 'IUse%'|sed 's/%//'|awk '$5=='$j' {print $1,$5}'` fi done if [ -e iuse ]; then python /data/python/mail.py $ma "Filesystem IUse% > 85%" "$iuse" fi
描述:
有一臺服務器做爲web應用,有一個目錄(/data/web/attachment)不定時地會被用戶上傳新的文件,可是不知道何時會上傳。因此,須要咱們每5分鐘作一次檢測是否有新文件生成。
請寫一個shell腳本去完成檢測。檢測完成後如果有新文件,還須要將新文件的列表輸出到一個按年、月、日、時、分爲名字的日誌裏。請不要想的太複雜,核心命令只有一個 find /data/web/attachment -mmin -5
思路: 每5分鐘檢測一次,那確定須要有一個計劃任務,每5分鐘去執行一次。腳本檢測的時候,就是使用find命令查找5分鐘內有過更新的文件,如果有更新,那這個命令會輸出東西,不然是沒有輸出的。固,咱們能夠把輸出結果的行數做爲比較對象,看看它是否大於0。
參考答案
#!/bin/bash d=`date -d "-5 min" +%Y%m%d%H%M` echo $d basedir=/data/shell/attachment find $basedir/ -type f -mmin -5 >/tmp/newf.txt n=`wc -l /tmp/newf.txt|awk '{print $1}'` echo %n if [ $n -gt 0 ]; then /bin/mv /tmp/newf.txt /tmp/$d fi
衍生: ls --full-time|awk '{OFS=" " } {print $6,$9}'>/tmp/filelist.txt
描述:寫一個shell腳原本看看你使用最多的命令是哪些,列出你最經常使用的命令top10。
sort /root/.bash_history|uniq -c|sort -nr|head
描述:假如咱們須要每小時都去執行你寫的腳本。在腳本中實現這樣的功能,當時間是0點和12點時,須要將目錄/data/log/下的文件所有清空,注意只能清空文件內容而不能刪除文件。而其餘時間只須要統計一下每一個文件的大小,一個文件一行,輸出到一個按日期和時間爲名字的日誌裏。 須要考慮/data/log/目錄下的二級、三級、… 等子目錄裏面的文件。
#!/bin/bash logdir='/data/shell/log' t=`date +%H` d=`date +%T` echo $d >/tmp/logsize for log in `find $logdir -type f` do if [ $t == "0" ] || [ $t == "12" ] then ture >$log else du -sh $log >>/tmp/logsize fi done