天天看點

Shell練習題(2)

(1)監控80端口

寫一個腳本,判斷本機的80端口是否開啟着,如果開啟着什麼都不做,如果發現端口不存在,那麼重新開機一下httpd服務,并發郵件通知你自己。腳本寫好後,可以每一分鐘執行一次,也可以寫一個死循環的腳本,30s檢測一次。

<code>#! /bin/bash</code>

<code>[email protected]</code>

<code>if</code> <code>netstat</code> <code>-lnp |</code><code>grep</code> <code>':80'</code> <code>|</code><code>grep</code> <code>-q </code><code>'LISTEN'</code><code>; </code><code>then</code>

<code>    </code><code>exit</code>

<code>else</code>

<code>    </code><code>/usr/local/apache2/bin/apachectl</code> <code>restart &gt;</code><code>/dev/null</code> <code>2&gt; </code><code>/dev/null</code>

<code>    </code><code>python mail.py $mail </code><code>"check_80"</code> <code>"The 80 port is down."</code>

<code>    </code><code>n=`</code><code>ps</code> <code>aux |</code><code>grep</code> <code>httpd|</code><code>grep</code> <code>-cv </code><code>grep</code><code>`</code>

<code>    </code><code>if</code> <code>[ $n -</code><code>eq</code> <code>0 ]; </code><code>then</code>

<code>        </code><code>/usr/local/apache2/bin/apachectl</code> <code>start 2&gt;</code><code>/tmp/apache_start</code><code>.err</code>

<code>    </code><code>fi</code>

<code>    </code><code>if</code> <code>[ -s </code><code>/tmp/apache_start</code><code>.err ]; </code><code>then</code>

<code>        </code><code>python mail.py  $mail  </code><code>'apache_start_error'</code>   <code>`</code><code>cat</code> <code>/tmp/apache_start</code><code>.err`</code>

<code>fi</code>

(2) 域名代理

内網有一台機器不能連外網,是以沒有辦法使用yum,考慮過使用iptables nat 轉發上網,但因為一些原因,放棄使用。是以想到nginx代理,原理很簡單。 A 不能通路 1網站, B可以通路,A和B可以内網通信,是以可以讓B作為A的代理。 并且可以限定通路的來源IP,配置檔案如下:

<code>server {</code>

<code>    </code><code>listen       80;</code>

<code>    </code><code>server_name aaa.com bbb.com  ccc.com ddd.com eee.com;</code>

<code>    </code><code>location / {</code>

<code>        </code><code>resolver 119.29.29.29;</code>

<code>        </code><code>proxy_pass       http://$host;</code>

<code>        </code><code>proxy_set_header Host      $host;</code>

<code>        </code><code>proxy_set_header X-Real-IP $remote_addr;</code>

<code>        </code><code>allow 192.168.5.0/24;</code>

<code>        </code><code>deny all;</code>

<code>    </code><code>}</code>

<code>}</code>

<code>說明:這裡的119.29.29.29 為一個DNS的ip,用resolver來指定。</code>

<code>假如B機器内網ip為 192.168.5.11,隻需要在A上加一條hosts192.168.5.11 aaa.com bbb.com ccc.com ddd.com eee.com</code>

(3)備份資料庫

設計一個shell腳本來備份資料庫,首先在本地伺服器上儲存一份資料,然後再遠端拷貝一份,本地儲存一周的資料,遠端儲存一個月。

假定,我們知道mysql root賬号的密碼,要備份的庫為discuz,本地備份目錄為/bak/mysql, 遠端伺服器ip為192.168.123.30,遠端提供了一個rsync服務,備份的位址是 192.168.123.30::backup . 寫完腳本後,需要加入到cron中,每天淩晨3點執行。

<code>### backup mysql data</code>

<code>### Writen by Aming.</code>

<code>PATH=</code><code>/usr/local/sbin</code><code>:</code><code>/usr/local/bin</code><code>:</code><code>/sbin</code><code>:</code><code>/bin</code><code>:</code><code>/usr/sbin</code><code>:</code><code>/usr/bin</code><code>:</code><code>/usr/local/mysql/bin</code>

<code>d1=`</code><code>date</code> <code>+%w`</code>

<code>d2=`</code><code>date</code> <code>+%d`</code>

<code>pass=</code><code>"your_mysql_password"</code>

<code>bakdir=</code><code>/bak/mysql</code>

<code>r_bakdir=192.168.123.30::backup</code>

<code>exec</code> <code>1&gt;</code><code>/var/log/mysqlbak</code><code>.log 2&gt;</code><code>/var/log/mysqlbak</code><code>.log</code>

<code>echo</code> <code>"mysql backup begin at `date +"</code><code>%F %T</code><code>"`."</code>

<code>mysqldump -uroot -p$pass --default-character-</code><code>set</code><code>=gbk discuz &gt;$bakdir/$d1.sql</code>

<code>rsync</code> <code>-az $bakdir/$d1.sql $r_bakdir/$d2.sql</code>

<code>echo</code> <code>"mysql backup end at `date +"</code><code>%F %T</code><code>"`."</code>

<code>然後加入</code><code>cron</code>

<code>0 3 * * * </code><code>/bin/bash</code> <code>/usr/local/sbin/mysqlbak</code><code>.sh</code>

(4)自動重新開機nginx服務

伺服器上跑的是LNMP環境,近期總是有502現象。502為網站通路的狀态碼,200正常,502錯誤是nginx最為普通的錯誤狀态碼。由于502隻是暫時的,并且隻要一重新開機php-fpm服務則502消失,但不重新開機的話,則會一直持續很長時間。是以有必要寫一個監控腳本,監控通路日志的狀态碼,一旦發生502,則自動重新開機一下php-fpm。

我們設定:

access_log /data/log/access.log

腳本死循環,每10s檢測一次(假設每10s鐘的日志條數為300左右)

重新開機php-fpm的方法是 /etc/init.d/php-fpm restart

<code>log=</code><code>/data/log/access</code><code>.log</code>

<code>N=10</code>

<code>while</code> <code>:; </code><code>do</code>

<code>    </code><code>##因為10秒鐘大概産生300條日志</code>

<code>    </code><code>tail</code> <code>-n 300 $log &amp;gt; </code><code>/tmp/log</code>

<code>    </code><code>n_502=`</code><code>grep</code> <code>-c </code><code>' 502"'</code> <code>/tmp/log</code><code>`</code>

<code>    </code><code>if</code> <code>[ $n_502 -</code><code>ge</code> <code>$N ]; </code><code>then</code>

<code>        </code><code>##記錄系統的狀态</code>

<code>        </code><code>top</code> <code>-bn1 &gt;</code><code>/tmp/</code><code>`</code><code>date</code> <code>+%H%M%S`-</code><code>top</code><code>.log</code>

<code>        </code><code>vmstat 1 5 &gt;</code><code>/tmp/</code><code>`</code><code>date</code> <code>+%H%M%S`-vm.log</code>

<code>        </code><code>/etc/init</code><code>.d</code><code>/php-fpm</code> <code>restart 2&gt;</code><code>/dev/null</code>

<code>        </code><code>##重新開機php-fpm服務後,應先暫緩1分鐘,而後繼續每隔10s檢測一次</code>

<code>        </code><code>sleep</code> <code>60</code>

<code>    </code><code>fi</code>    

<code>    </code><code>sleep</code> <code>10</code>

<code>done</code>

(10)删除文本中的字母

要求: 把一個文本文檔的前5行中包含字母的行删除掉,同時把6到10行中的全部字母删除掉。

<code>假設文本名字叫做1.txt,并且文本行數大于10,腳本如下</code>

<code>#!/bin/bash</code>

<code>##先擷取該文本的行數</code>

<code>nu=`</code><code>wc</code> <code>-l 1.txt |</code><code>awk</code> <code>'{print $1}'</code><code>`</code>

<code>##對前5行程序處理</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>seq</code> <code>1 5`</code>

<code>do</code> 

<code>    </code><code>##使用sed把每一行的内容指派給變量</code>

<code>    </code><code>l=`</code><code>sed</code> <code>-n </code><code>"$i"</code><code>p 1.txt`</code>

<code>    </code><code>##用grep 判定是否比對字母,-v取反,-q不輸出内容</code>

<code>    </code><code>if</code> <code>echo</code> <code>$l |</code><code>grep</code> <code>-vq </code><code>'[a-zA-Z]'</code>

<code>    </code><code>then</code>

<code>    </code><code>echo</code> <code>$l</code>

<code>##對6-10行做删除字母處理</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>seq</code> <code>6 10`</code>

<code>do</code>

<code>    </code><code>echo</code> <code>$l|</code><code>sed</code> <code>'s/[a-zA-Z]//g'</code>

<code>##剩餘的直接輸出</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>seq</code> <code>11 $nu`</code>

<code>    </code><code>sed</code> <code>-n </code><code>"$i"</code><code>p 1.txt</code>

<code>##若想把更改内容寫入到1.txt,還需要把以上内容重定向到一個文本中,然後删除1.txt,再把剛剛重定向的檔案更名為1.txt</code>

<code></code>

本文轉自Grodd51CTO部落格,原文連結:http://blog.51cto.com/juispan/1951343,如需轉載請自行聯系原作者