-
Notifications
You must be signed in to change notification settings - Fork 1
/
shell.xml
239 lines (224 loc) · 6.96 KB
/
shell.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Author: netkiller $ -->
<!-- $Id$ -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V5.0//EN"
"/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd" [
<!ENTITY article.author.xml SYSTEM "../common/article.author.xml">
<!ENTITY book.info.legalnotice.xml SYSTEM "../common/book.info.legalnotice.xml">
<!ENTITY book.info.abstract.xml SYSTEM "../common/book.info.abstract.xml">
]>
<article xml:base="http://netkiller.sourceforge.net/article/" xmlns="http://docbook.org/ns/docbook" xml:lang="zh-cn">
<articleinfo>
<title>Shell 高级编程</title>
<subtitle>http://netkiller.github.io/journal/shell.html</subtitle>
&article.author.xml;
&book.info.legalnotice.xml;
<abstract>
<para>Shell 更多是被看成一种批处理命令,确实很多是是吧 Shell当成批处理去使用的。</para>
<para>我确不这么看,我认为要想开发程序一样去写Shell,把Shell当成一种语言。</para>
<para>我们需要将很多软件开发技巧应用在Shell领域</para>
</abstract>
&book.info.abstract.xml;
<keywordset>
<keyword>iptables</keyword>
<keyword>access.log</keyword>
<keyword>error.log</keyword>
</keywordset>
<pubdate>$Data$</pubdate>
<releaseinfo>$Id$</releaseinfo>
</articleinfo>
<section>
<title>递归调用</title>
<para>不懂递归不算是合格的程序员</para>
<para>递归调用是一种特殊的嵌套调用,是一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。</para>
<screen>
<![CDATA[
#!/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
]]>
</screen>
<para>运行上面的程序</para>
<screen>
<![CDATA[
$ 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"
]]>
</screen>
</section>
<section>
<title>实现守护进程</title>
<para>无论是C语言还是php/python/perl 通过fork命令实现守护进程,让当前程序进入后台运行,这种手段常常用于服务器软件。</para>
<para>启用 shell 解决重复运行问题,记录PID以便可以停止Shell运维</para>
<screen>
<![CDATA[
#!/bin/bash
##############################################
# $Id$
# Author: Neo <[email protected]>
# 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 $?
]]>
</screen>
</section>
<section>
<title>进程间通信</title>
<para>进程间通信就是在不同进程之间传播或交换信息。</para>
<para>脚本具有黑白名单功能,一个进程专门负责采集数据,另一个进程专门负责处理由第一个进程发送过来的数据。</para>
<screen>
<![CDATA[
#!/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
]]>
</screen>
<para>首先启动第一个进程,准备接收数据</para>
<screen>
<![CDATA[
# ipfw process
]]>
</screen>
<para>然后启动第二个进程,发送采集数据</para>
<screen>
<![CDATA[
# ipfw collect
]]>
</screen>
<para>这个程序使用管道作为进程见通信手段,所以只能在一个系统下运行,如果改为Socket通信就可以实现跨服务器数据处理</para>
</section>
<section>
<title></title>
<screen>
<![CDATA[
]]>
</screen>
</section>
</article>