Shell 高級編程

Shell 高級編程

原創 2016-11-04 景峯 Netkillerphp

Shell 高級編程

http://netkiller.github.io/journal/shell.html

Mr. Neo Chen (陳景峯), netkiller, BG7NYT


中國廣東省深圳市龍華新區民治街道溪山美地
518131
+86 13113668890

<netkiller@msn.com>html

$Id: shell.xml 449 2012-08-10 10:38:08Z netkillerpython

版權聲明git

轉載請與做者聯繫,轉載時請務必標明文章原始出處和做者信息及本聲明。程序員

 

Shell 更可能是被當作一種批處理命令,確實不少是是吧 Shell當成批處理去使用的。github

我確不這麼看,我認爲要想開發程序同樣去寫Shell,把Shell當成一種語言。web

咱們須要將不少軟件開發技巧應用在Shell領域shell

 

目錄編程

  • 1. 遞歸調用bash

  • 2. 實現守護進程

  • 3. 進程間通訊

  • 4.

 

1. 遞歸調用

不懂遞歸不算是合格的程序員

遞歸調用是一種特殊的嵌套調用,是一個函數在它的函數體內調用它自身稱爲遞歸調用。這種函數稱爲遞歸函數。

#!/bin/bash
########################################
# Author: Neo <netiller@msn.com>
# Home : http://netkiler.github.io
# Project: https://github.com/oscm/shell
########################################
domain=$1
########################################
function include(){
	txt=$1
	for host in $(echo $txt | egrep -o "include:(.+) ")
	do
		txt=$(dig $(echo $host | cut -d":" -f2) txt | grep "v=spf1")
		echo $txt;
		if [ "$(echo $txt | grep "include")" ]; then
			include "$txt"
		fi
	done
}
function main(){
	spf=$(dig ${domain} txt | grep "v=spf1")
	echo $spf

	if [ "$(echo $spf | grep "include")" ]; then
		include "$spf"
	fi
}

main $domain

運行上面的程序

$ bash spf.sh 163.com
163.com. 6878 IN TXT "v=spf1 include:spf.163.com -all"
spf.163.com. 16991 IN TXT "v=spf1 include:a.spf.163.com include:b.spf.163.com include:c.spf.163.com include:d.spf.163.com -all"
a.spf.163.com. 8001 IN TXT "v=spf1 ip4:220.181.12.0/22 ip4:220.181.31.0/24 ip4:123.125.50.0/24 ip4:220.181.72.0/24 ip4:123.58.178.0/24 ip4:123.58.177.0/24 ip4:113.108.225.0/24 ip4:218.107.63.0/24 ip4:123.58.189.128/25 -all"
b.spf.163.com. 10131 IN TXT "v=spf1 ip4:176.34.21.58 ip4:176.34.53.178 ip4:121.195.178.48/28 ip4:223.252.213.0/24 -all"
c.spf.163.com. 17199 IN TXT "v=spf1 ip4:223.252.206.0/24 ip4:43.230.90.0/27 -all"
d.spf.163.com. 17615 IN TXT "v=spf1 ip4:123.126.65.0/24 ip4:106.2.88.0/24 ip4:220.181.97.0/24 ip4:180.150.142.123 ip4:180.150.142.124 ip4:180.150.154.88 ip4:180.150.154.92 ip4:180.150.154.93 ip4:103.251.128.69 -all"

2. 實現守護進程

不管是C語言仍是php/python/perl 經過fork命令實現守護進程,讓當前程序進入後臺運行,這種手段經常用於服務器軟件。

啓用 shell 解決重複運行問題,記錄PID以即可以中止Shell運維

#!/bin/bash
##############################################
# $Id: shell.xml 449 2012-08-10 10:38:08Z netkiller $
# Author: Neo <netiller@msn.com>
# Home : http://netkiler.github.io
# Project: https://github.com/oscm/shell
##############################################
NAME=info
BASEDIR='/www'
PROG=$BASEDIR/bin/$(basename $0)
LOGFILE=/var/tmp/$NAME.log
PIDFILE=/var/tmp/$NAME.pid
##############################################
PHP=/usr/local/webserver/php/bin/php
##############################################
#echo $$
#echo $BASHPID
function start(){
	if [ -f "$PIDFILE" ]; then
		echo $PIDFILE
		exit 2
	fi

	for (( ; ; ))
	do
		cd $BASEDIR/crontab/
		$PHP readfile.php > $LOGFILE
		$PHP chart_gold_silver_xml.php > /dev/null
		sleep 60
	done &
	echo $! > $PIDFILE
}
function stop(){
  	[ -f $PIDFILE ] && kill `cat $PIDFILE` && rm -rf $PIDFILE
}

case "$1" in
  start)
  	start
	;;
  stop)
  	stop
	;;
  status)
  	ps ax | grep chart.xml | grep -v grep | grep -v status
	;;
  restart)
  	stop
	start
	;;
  *)
	echo $"Usage: $0 {start|stop|status|restart}"
	exit 2
esac

exit $?

3. 進程間通訊

進程間通訊就是在不一樣進程之間傳播或交換信息。

腳本具備黑白名單功能,一個進程專門負責採集數據,另外一個進程專門負責處理由第一個進程發送過來的數據。

#!/bin/bash           
########################################  
# Homepage: http://netkiller.github.io  
# Author: neo <netkiller@msn.com>  
########################################  
BLACKLIST=/tmp/BLACKLIST.lst  
PIPE=/tmp/pipe  
pidfile=/tmp/firewall.pid  
KEYWORD=XXDD0S  
ACCESSLOG=/www/logs/www.example.com/access.$(date +'%Y-%m-%d').log  
########################################  
if [ -z $1 ]; then  
    echo "$0 clear|fw|collect|process|close"  
fi
  
if [ "$1" == "clear" ]; then  
    rm -rf $BLACKLIST  
    rm -rf $PIPE  
    echo "Clear OK!!!"  
fi
  
if [ "$1" == "close" ]; then  
        kill `cat $pidfile`  
    echo > $pidfile  
fi
  
if [ ! -f $BLACKLIST ]; then  
    touch $BLACKLIST  
fi  
  
if [ ! -e $PIPE ]; then  
    mkfifo $PIPE  
fi  
  
if [ "$1" == 'fw' ]; then  
    iptables -A OUTPUT -p tcp --dport 2049 -j REJECT  
    iptables -A OUTPUT -p tcp -m multiport --dports 22,21 -j REJECT  
fi  
  
if [ "$1" == "collect" ]; then  
    killall tail
    for (( ; ; ))  
    do  
        tail -f $ACCESSLOG | grep $KEYWORD | cut -d ' ' -f1 > $PIPE  
    done &  
    echo $! > $pidfile  
fi  
  
if [ "$1" == "process" ]; then  
for (( ; ; ))  
do  
    while read line   
    do  
        grep $line ${BLACKLIST}
        if [ $? -eq 1 ] ; then  
            echo $line >> ${BLACKLIST}
            iptables -I INPUT -p tcp --dport 80 -s $line -j DROP      
        fi  
    done < $PIPE  
done &  
echo $! >> $pidfile  
fi

首先啓動第一個進程,準備接收數據

# ipfw process

而後啓動第二個進程,發送採集數據

# ipfw collect

這個程序使用管道做爲進程見通訊手段,因此只能在一個系統下運行,若是改成Socket通訊就能夠實現跨服務器數據處理

 

 

延伸閱讀

PostgreSQL·帳戶表/餘額表/消費儲蓄表

PostgreSQL·國家地區表的設計

PHP高級編程之守護進程

PHP高級編程之多線程

PHP高級編程之消息隊列

 

做者:netkiller

網站:http://www.netkiller.cn

郵箱:netkiller@msn.com

公衆號:netkiller-ebook

關注做者公衆號,每日推送原創文章。若是已有什麼建議,請給我留言。

 

相關文章
相關標籤/搜索