侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

Shell 高级编程

2023-12-13 星期三 / 0 评论 / 0 点赞 / 101 阅读 / 7063 字

Shell 高级编程 原创2016-11-04景峯Netkiller Shell 高级编程 http://netkiller.github.io/journal/shell.html Mr.Neo C

Shell 高级编程

原创 2016-11-04 景峯 Netkiller

Shell 高级编程

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

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


中国广东省深圳市龙华新区民治街道溪山美地
518131
+86 13113668890

<[email protected]>

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

版权声明

转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。

 

Shell 更多是被看成一种批处理命令,确实很多是是吧 Shell当成批处理去使用的。

我确不这么看,我认为要想开发程序一样去写Shell,把Shell当成一种语言。

我们需要将很多软件开发技巧应用在Shell领域

 

目录

  • 1. 递归调用

  • 2. 实现守护进程

  • 3. 进程间通信

  • 4.

 

1. 递归调用

不懂递归不算是合格的程序员

递归调用是一种特殊的嵌套调用,是一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。

#!/bin/bash######################################### Author: Neo <[email protected]># 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.com163.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 <[email protected]># Home : http://netkiler.github.io# Project: https://github.com/oscm/shell##############################################NAME=infoBASEDIR='/www'PROG=$BASEDIR/bin/$(basename $0)LOGFILE=/var/tmp/$NAME.logPIDFILE=/var/tmp/$NAME.pid##############################################PHP=/usr/local/webserver/php/bin/php###############################################echo $$#echo $BASHPIDfunction 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 2esacexit $?

3. 进程间通信

进程间通信就是在不同进程之间传播或交换信息。

脚本具有黑白名单功能,一个进程专门负责采集数据,另一个进程专门负责处理由第一个进程发送过来的数据。

#!/bin/bash           ########################################  # Homepage: http://netkiller.github.io  # Author: neo <[email protected]>  ########################################  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高级编程之消息队列

 

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

邮箱:[email protected]

公众号:netkiller-ebook

关注作者公众号,每日推送原创文章。如果已有什么建议,请给我留言。

 

广告 广告

评论区