﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-1，2，3。。。 大道以多岐路亡羊，学者以多方丧生。-随笔分类-软件的使用</title><link>http://www.cnitblog.com/schkui/category/2841.html</link><description>政府为什么敢控制物价，不敢控制房价，---- 因为为房，是(多或少)数官员和大商人的一起的利益。。。怕影响自己的政绩...    </description><language>zh-cn</language><lastBuildDate>Sun, 11 Dec 2011 04:25:11 GMT</lastBuildDate><pubDate>Sun, 11 Dec 2011 04:25:11 GMT</pubDate><ttl>60</ttl><item><title>Enterprise Architect 8.0.864下载及注册码</title><link>http://www.cnitblog.com/schkui/archive/2011/12/05/76521.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Mon, 05 Dec 2011 03:56:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2011/12/05/76521.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/76521.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2011/12/05/76521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/76521.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/76521.html</trackback:ping><description><![CDATA[<div>{9699EED2-BE87-9ee4-9996-9BAE4-FW71-DAWA-VG5W-4RUQ-C0}</div>
<div>{880300E9-20C2-18c4-A5C0-4D322-FW70-E936-8362-4EQA-C0}</div>
<div>{4B2DEEBC-C889-653a-3158-3545C-FW70-A5CM-UU9K-NGK3-C0}</div>
<div>{27B034BE-E297-d84e-02B5-C05D1-FW71-C70N-QO3O-E0AO-C0}</div>------------------------ 
<div>低版本的也能用，而且，7.0的keygen生成的key也能用在8.0.864上面。</div>
<div><br /></div>
<div><font color="#ff0000"><strong>在官网下载的试用版无法使用这些key</strong></font>，请从下面的链接进行下载。</div>
<div><br /></div>
<div>下载：<a href="http://u.115.com/file/f9f63fb1e5" rel="nofollow" target="_blank"><font color="#294a09">115网盘下载</font></a>&nbsp;</div><wbr>  <img src ="http://www.cnitblog.com/schkui/aggbug/76521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2011-12-05 11:56 <a href="http://www.cnitblog.com/schkui/archive/2011/12/05/76521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ettercap-交换环境下的嗅探器使用方法  </title><link>http://www.cnitblog.com/schkui/archive/2007/12/05/37358.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Wed, 05 Dec 2007 06:44:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/12/05/37358.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/37358.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/12/05/37358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/37358.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/37358.html</trackback:ping><description><![CDATA[一:安装<br><br>你可以在网上很多地方下载到它的最新版本,比如<a href="http://ettercap.sourceforge.net/" target="_blank">http://ettercap.sourceforge.net</a> 下载完后,先解压缩:<br>[root@CIEL root]#tar zxpvf ettercap-0.6.tar.gz<br>[root@CIEL root]#cd ettercap-0.6<br>[root@CIEL ettercap-0.6]#./configure&amp;&amp;make&amp;&amp;make install<br>[root@CIEL ettercap-0.6]#make plug-ins<br>[root@CIEL ettercap-0.6]#make plug-ins_install<br>安装完成后,输入"ettercap --help"就可以看见帮助文档.基本用法是<br>ettercap [option] [host:port] [host:port] [mac] [mac]<br><br>二：功能介绍<br><br>嗅探：它有5种工作模式<br>-a --arpsniff 基于arp的欺骗,分3小种：arpbased,smartcarp和publicarp<br>-s --sniff 属于IPBASED,目标可以是任何主机<br>-m --macsniff 属于MACBASED<br><br>需
要说明的是-s
-m两选项带来的是传统嗅探模式,分别基于IP地址和MAC地址.也就是说它们必需先把网卡置于混杂,然后才可以正常工作。所以在交换环境下,这两项会完
全失效,-a选项是基于ARP欺骗的,是一种中间人攻击模型。实质是利用了ARP协议的漏洞，攻击者分别欺骗了A和B机。让A机把数据传给嗅探者,然后再
由嗅探机器把数据转发给B机,A和B却没有意识到数据包的中转过程，这样我们就可以劫获数据甚至修改数据包.<br><br>下面分别介绍五种用法:<br>1：ettercap -Nza ip1 ip2 mac1 mac2 (arpbased) 劫获IP1与IP2间的数据.缺省状态下<br>只接收TCP数据包<br><br>2：
ettercap -Na ip mac (smartcarp)
劫获此ip与外部所有通讯数据,这种方式比较剧烈,启动时采用的是ARP风暴,很容易被发现.如果别人在用TCPDUMP监听,就会看见攻击者发出的无数
的ARP请求,再傻的管理员都明白什么事情发生了.不过由于修改了指定主机的ARP表中关于被监听主机的MAC地址，还修改了被监听主机中的那些指定主机
的MAC地址,处在完全的中间人工作状态，这时候你可以作的事情多些,比如更改数据包,截取SSH口令.<br><br>3：ettercap
-Nza ip mac (publicarp)
同上,不同点在于发送ARP请求的方式,上面采用的是ARP广播,这里只是对特定主机发送ARP请求.这样,不易引起管理员的怀疑.不过也带来了问题,被
监听者自己也会收到这个以广播方式发送的ARP响应包,于是便会弹出"检测到IP地址于硬件地址冲突"之类的警告.不过不会影响目标主机正常通信,还有一
点就是发往被监听主机的数据包会送给监听者，而监听者发出的数据包却被直接送往真正的目的主机，没有经过监听者的主机.所以我们只能截取不完全的通信内
容.<br><br>4：ettercap -Nzs IP:80 (ipbased sniffing) 基于IP地址的嗅探。这里仅劫获目标机器HTTP消息,你也可以指定其他端口，比如23 。如果没有指定，所有都会被截取<br><br>5：ettercap -zm mac1 mac 2 (macbased) 基于MAC的嗅探.只要输入MAC地址<br><br>需
要说明的是，4，5两种方式只适合于共享网络,在交换网络下一概无效.MAC地址的获取很简单，直接在终端输入&#8220;ettercap
-l"就会列出所有在线主机。或者你先PING一下某个IP，不管有没有回应（没有回应可能是对方开了防火墙），再用ARP命令就可以获取其MAC地址。
如果无法获取，则此IP不存在 ,这也是探测防火墙后的主机是否在线的一个好方法。<br><br>包过滤：由于网络流量实在很大，当你面对大量记录数据
时，你可能会感到手足无措，你想找到自己需要的数据无疑是一项艰巨的工作，这时侯，我们可以通过—F
选项加载自己的过滤规则，这样，很多无用的数据就会被忽略，删节。和注射字符一样，我们进行包过滤时有必要的话也要注意到正确的TCP序列号和确认序列号
等因素。一旦你加载了自己的过滤链，你就可以有目的的得到自己最需要的数据了。一条过滤规则看起来就象汇编程序一样，当然，还是有差距的，用列阵形容可能
更确切些。一条过滤规则大概如下：《协议，源端口，目标端口，承载数据》<br><br>一个空的搜索字符串总可以成立，比如端口如果没有指定，所有的都会被记录下来。只要那些规则匹配，你的过滤链就可以工作了.<br><br>例如有如下数据流<br>packet 1: "var1=123&amp;var2=400"<br>packet 2: "var1=124&amp;var2=420"<br>packet 3: "var1=125&amp;var2=460"<br>packet 4: "var1=126&amp;var2=540"<br>packet 5: "var1=127&amp;var2=700<br>......<br>......<br>我们可以写如下规则<br>Search: "var1=[3*]"<br>Replace: "var1=000"<br>被过滤后的流就会如下<br>packet 1: "var1=000&amp;var2=400"<br>packet 2: "var1=000&amp;var2=420"<br>packet 3: "var1=000&amp;var2=460"<br>packet 4: "var1=000&amp;var2=540"<br>packet 5: "var1=000&amp;var2=700"<br>如果&#8220;var1&#8221;后面没有被指定，默认则&#8220;var1=000&#8221;<br><br>最后是关于ssh的嗅探：<br><br>由于传输数据被加密,我们必需自己掌握密钥,具体实现方法如下:我们先截取服务器的明码密钥,保存在一边.自己再生成另一明码密钥,用来加密本机与客户机通讯数据,收到客户机数据后,自然可以解密,在用服务器明码密钥加密,发送给服务器,如此一来,可以偷天换柱.<br><br>三：工作参数：<br><br>下面列出它的主要选项,虽然它本身有28个,不过限于篇幅,下面只列出一些常用的:<br>-N --simple 非交互方式，很常用的<br>-z --silent 静模式(启动时不是发送ARP风暴)<br>-O --passive 被动模式嗅探<br>-b --broadping 广播PING ,替代了ARPPING<br>-S --spoof &lt;ip1&gt; 用IP1这地址发送ARP请求获取其他机器信息<br>-H --hosts &lt;ip1[ip2][...]&gt; 嗅探的目标主机的IP,可以是很多台<br>-n --netmask &lt;netmask&gt; 扫描由输入子网掩码确定的子网<br>-v --version 检查最新版本<br>-h --help 帮助文档<br><br>组合选项 (一般和N绑定一齐执行)<br>-u --udp 嗅探UDP数据,缺省是TCP<br>-p --plugin &lt;name&gt; 运行指定名字的插件<br>-l --list 列出所有在线主机ip和mac.实质就是发送255个ARP请求,等待回音,如果你的子网掩码是255.255.0.0,就会发送255*255个请求,就是ARP风暴吧!<br>-C --colletc 仅搜集用户名和对应密码 Eg:ettetcap -NCzs IP：port 它规则不是很严格，所以你IP或PORT不填也没有关系<br>-c --check 检察网络里有没其他机器正在嗅探<br>-x
--hexview
用16进制表达数据,这样,如果你想自己创建一个包的话会比较方便.比如建个文件写上"\x01\x02\x00\x00\xFF\xFF\x00\
x02here the pass".注意:ettercap不仅可以嗅探包,也可以创建包的.所以你可以更改穿过你机器的任何一段数据<br>-L --logtofile 记录所有数据到指定位置<br>-k --newcert 创建一个新的CERT文件,用以进行HTTPS攻击<br>-F --filter 从指定文件列加载过滤规则<br>-f --fingerprint &lt;host&gt; 指定主机的OS判别,采用的是nmap的数据库,所以准确性得到保障,不过也有无法辨别的时候.<br>-t --linktype 判断自己处在什么样的网络环境中，交换或是HUB<br><br>实战篇<br>210.197.248.192是确定在线的主机，先判断它操作系统<br>[root@CIEL root]# ettercap -Nf 218.197.248.192<br>ettercap 0.6.0 (c) 2001 ALoR &amp; NaGA<br>Your IP: 218.197.248.226 with MAC: 00:00:E8:7B:CA:4E on Iface: eth0<br>Fingerprinting 218.197.248.192...<br>Operating System:<br>Windows NT 5 Beta2 or Beta3<br>Windows Me or Windows 2000 RC1 through final release<br>MS Windows2000 Professional RC1/W2K Advance Server Beta3<br>Windows Millenium Edition v4.90.3000<br><br>现在小试牛刀，看看对方正在做什么<br>[root@CIEL root]# ettercap -Nza 218.197.248.192 218.197.248.254 MAC1 MAC2<br><br>这
里218.197.248.254是网关。这样，我们就是中间人了，它与外网所有数据都会在我们这里流过。不过被嗅探机器的内网数据交换我们将看不到.下
面是截取到的2段典型的HTTP交互数据，从第一段可以看出客户正在看的网页，脚本，浏览器语言以及客户的操作系统等信息。从第2段可以看出主机的
bannner等等,都是网站的基本资料<br>GET /pcedu/script/title_edu.js HTTP/1.1.<br>Accept: */*.<br>Referer: <a href="http://wwwb.pconline.com.cn/pcedu/soft/doc/nt/10308.htm." target="_blank">http://wwwb.pconline.com.cn/pcedu/soft/doc/nt/10308.htm.</a><br>Accept-Language: zh-cn.<br>Accept-Encoding: gzip, deflate.<br>If-Modified-Since: Mon, 09 Sep 2002 09:18:53 GMT.<br>If-None-Match: "6f67c-2d5-3d7c677d".<br>User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt).<br>Host: wwwb.pconline.com.cn.<br>Connection: Keep-Alive.<br><br>HTTP/1.1 200 OK.<br>Date: Sat, 01 Mar 2003 08:25:37 GMT.<br>Server: Apache/1.3.20 (Unix) PHP/4.1.2 mod_ssl/2.8.4 OpenSSL/0.9.6a.<br>X-Powered-By: PHP/4.1.2.<br>Keep-Alive: timeout=15, max=100.<br>Connection: Keep-Alive.<br>Transfer-Encoding: chunked.<br>Content-Type: text/html.<br><br>当
然，它还可以记下很多网页内容，全是HTML源代码，你可以抓下来，用HTM后缀保存，再用浏览器打开，好了，你看到的是什么，别人看到的就是什么。不过
它对中文支持不很好，所以别人看见的中文你将无法看到，另一个程序LCRZOEX就很不错，在中文终端里，可以把所有中文网页完整抓下来。<br><br>一般黑客最感兴趣的无非是密码了，比如下面的组合，h是帮助，它会提供帮助信息<br>[root@CIEL root]# ettercap -NCzs<br>ettercap 0.6.0 (c) 2001 ALoR &amp; NaGA<br>Your IP: 218.197.248.226 with MAC: 00:00:E8:7B:CA:4E on Iface: eth0<br>Resolving 1 hostnames...<br>Press 'h' for help...<br>Sniffing (IP based): ANY:0 &lt;--&gt; ANY:0<br>TCP packets only... (default)<br>Collecting passwords...<br>[qQ] - quit<br>[lL] - log all trafic to file(s)<br>space - stop/cont sniffing<br><br>15:52:51 218.197.248.21:1027 &lt;--&gt; 61.114.4.41:23 telnet<br>USER: root<br>PASS: root<br><br>15:54:53 218.197.248.46:1041 &lt;--&gt; 61.135.132.99:80 http<br>USER:dalin<br>PASS:7895865<br><a href="http://www.sohu.com/" target="_blank">http://www.sohu.com/</a><br><br>16:13:14 218.197.248.192:2278 &lt;--&gt; 218.197.249.172:21 ftp<br>USER:
CshjPASS:
123456如果你输入lL,系统在/ROOT下会自动生成&#8220;20030301-Collected-passwords.log",里面会记录下所有能
嗅探到的密码，看来TELNET，HTTP，FTP密码都不能逃过，这些记录简洁明了，在机器上挂一天，不知道可以记录多少了：）
<br><img src ="http://www.cnitblog.com/schkui/aggbug/37358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2007-12-05 14:44 <a href="http://www.cnitblog.com/schkui/archive/2007/12/05/37358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Diff和Patch维护源码</title><link>http://www.cnitblog.com/schkui/archive/2007/06/14/28457.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Thu, 14 Jun 2007 09:25:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/06/14/28457.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/28457.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/06/14/28457.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/28457.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/28457.html</trackback:ping><description><![CDATA[在linux系统下，维护源码可以使用很多方法，简单的版本维护工作并没有必要使用复杂的CVS等专门的版本维护工具，linux标配中的diff和patch工具就可以完成代码的简单备份和升级工作。<br>&nbsp;&nbsp;&nbsp; diff以"行"为单位比较两个文件（也可以是目录较），并将不同之处以某种格式输出到指定输出上；patch可以读入这种输出，并按照一定指令使源文件（目录）按照目标文件（目录）更新。Linux内核源码就是按照这种方式保持更新的，我们在<a href="http://www.kernel.org/" target="_blank"><font color="#000000">www.kernel.org</font></a> 上可以下载到最新内核的patch文件的bzip2包。本文以介绍<font size="2">diff</font>和patch工具的使用。<br><br>1．<font color="#ff0000"><font color="#000000" size="2">diff</font><br></font><font size="2">diff</font>既
可以用来比较两个文件，也可以用来比较两个目录中每个文件。使用-r（--recursive）参数时还可以在目录中嵌套比较。比较目录时除比较同名文件
外，对不同名的文件当成新文件处理。对于比较C程序文件，diff还提供了专门的参数（-p，--show-c-function）来标识不同之处所在的
函数名。<br><br><font size="2">&nbsp;&nbsp;&nbsp; diff</font>的输出格式有三种：列举方式、命令模式和上下文模式，其中命令模式有分为两种：ed命令格式和RCS（Revision Control System，版本控制系统）命令格式，上下文模式也按格式分为老版和新版两种。<br>&nbsp;&nbsp;&nbsp; 新版格式较之老版要紧凑一些，Linux内核源码的升级就是按照新版上下文格式用diff组织的，比如patch-2.6.16中所用的具体命令为：<br><br><font color="#ff0000" size="-0"><strong> diff</strong> </font> -Nur linux-2.6.15 linux<br><br>参数N表示如果某个文件仅在一个目录中出现，则假定其在另一个目录中为空文件；u表示unified格式，r表示在目录中嵌套使用，linux-2.6.15显然是老核的目录名，而linux则为新核的目录名。<br><br>2．patch<br><br>尽管并没有指定patch和diff的关系，但通常patch都使用<font size="2">diff</font>的结果来完成打补丁的工作，这和patch本身支持多种<font size="2">diff</font>输出文件格式有很大关系。patch通过读入patch文件（可以从标准输入），对目标文件进行修改。通常先用<font size="2">diff</font>命令比较新老版本，patch命令文件则采用<font size="2">diff</font>的输出文件，从而保持原版本与新版本一致。<br><br>patch的标准格式为<br><br>patch [options] [originalfile] [patchfile]<br><br>如
果patchfile为空则从标准输入读取patchfile内容；如果originalfile也为空，则从patchfile中读取需要打补丁的文件
名。因此，如果需要修改的是目录，一般都必须在patchfile中记录目录下的各个文件名。绝大多数情况下，patch都用以下这种简单的方式使用：<br><br>patch -p[num] &lt;patchfile<br><br>patch命令可以忽略文件中的冗余信息，从中取出<font size="2">diff</font>的格式以及所需要patch的文件名，文件名按照<font size="2">diff</font>参数中的"源文件"、"目标文件"以及冗余信息中的"Index："行中所指定的文件的顺序来决定。也就是说，对于如下<font size="2">diff</font>结果文件（Linux内核源码2.6.16升级包，部分）：<br>
<div style="margin: 5px 20px 20px;">
<div class="smallfont" style="margin-bottom: 2px;">引用:</div>
<table border="0" cellpadding="4" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="alt2" style="border: 1px inset ;"><br><font size="2">diff</font><strong>  -Nur linux-2.6.15/Makefile linux/Makefile<br>--- linux-2.6.15/Makefile Thu Nov 22 17:22:58 2006<br>+++ linux/Makefile Sat Nov 24 16:21:53 2006<br>@@ -1,7 +1,7 @@<br>VERSION = 2<br>PATCHLEVEL = 6<br>-SUBLEVEL = 15<br>-EXTRAVERSION =-ubuntu<br>+SUBLEVEL = 16<br>+EXTRAVERSION =<br><br>KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)<br>&#8230;&#8230;</strong> <br></td>
        </tr>
    </tbody>
</table>
</div>
<br>patch
首先尝试当前目录（或者-d参数指定的目录）下的linux-2.6.15/Makefile文件是否存在，如果不存在则试图对
linux/Makefile文件操作，仅当两者都不存在时（或者设置了POSIXLY_CORRECT环境变量）才会读取Index:的内容（此文件中
没有标识）。<br><br>前面提到的-p参数决定了是否使用读出的源文件名的前缀目录信息，不提供-p参数，则忽略所有目录信息，-p0（或者-p
0）表示使用全部的路径信息，-p1将忽略第一个"/"以前的目录，依此类推。如/usr/src/linux-2.6.15/Makefile这样的文
件名，在提供-p3参数时将使用linux-2.6.15/Makefile作为所要patch的文件。<br><br>对于刚才举的Linux内核源码
2.6.16升级包的例子，假定源码目录位于/usr/src/linux中，则在当前目录为/usr/src时使用"patch -p0
&lt;patch-2.6.16"可以工作，在当前目录为/usr/src/linux时，"patch
-p1&lt;patch-2.4.16"也可以正常工作。<br><br>patch可以直接操作上下文格式以及混合ed格式的<font size="2">diff</font>输出文件，而将ed格式文件通过管道提交给ed程序操作。<br><br>3．配合使用<font size="2">diff</font>和patch升级源码<br><br>在此仅举一个简单的例子来说明如何用<font size="2">diff/</font>patch工具维护源码升级。<br><br>假设program-1.0目录中为旧版，现开发完成的新版位于program-2.0目录中，将两个目录置于同一父目录下，然后在该父目录上执行：<br><br><font color="#ff0000" size="-0"><strong> diff</strong> </font> -Nur program-1.0 program-2.0 &gt;program-2.0.patch<br><br>将生成一个program-2.0.patch的补丁文件，发布该补丁文件（可以先压缩成bzip2格式）。<br><br>假设拿到的是program-2.0.patch.bz2文件，则在program-1.0目录同级执行：<br><br>bzcat program-2.0.patch.bz2 | patch -p0<br><br>如此即完成了从1.0到2.0的升级。<br><br>如果希望恢复到原版本，可以使用-R（--reverse）参数。
<br><img src ="http://www.cnitblog.com/schkui/aggbug/28457.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2007-06-14 17:25 <a href="http://www.cnitblog.com/schkui/archive/2007/06/14/28457.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>emacs 的简单使用及配置 </title><link>http://www.cnitblog.com/schkui/archive/2007/05/30/27785.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Wed, 30 May 2007 07:52:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/05/30/27785.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/27785.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/05/30/27785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/27785.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/27785.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 使用tags之前要先对源代码分析建立tags文件，在代码所在目录中运行：etags -R 即可。
<div>
<p>我常用的就这几个命令和快捷键： </p>
<pre class="example">M-x visit-tags-table &lt;RET&gt; FILE &lt;RET&gt;   选择tags文件<br>M-. [TAG] &lt;RET&gt;                         访问标签<br>M-*                                     返回<br>C-u M-.                                 寻找标签的下一个定义<br></pre>
<pre class="example">
<p>cscope用用吧。它其实是一个独立的软件，完全可以脱离vi和emacs使用。但是结合emacs的强大功能，cscope就显得更加方便了。GNU Emacs默认自带cscope的支持。在使用之前，cscope也需要对代码进行索引。在emacs中可以这样做： </p>
<pre class="example">C-c s a             设定初始化的目录，一般是你代码的根目录<br>C-s s I             对目录中的相关文件建立列表并进行索引<br></pre>
<p>建完索引之后，你就可以用cscope在代码里游荡了。常用的一些命令如下： </p>
<pre class="example">C-c s s             序找符号<br>C-c s g             寻找全局的定义<br>C-c s c             看看指定函数被哪些函数所调用<br>C-c s C             看看指定函数调用了哪些函数<br>C-c s e             寻找正则表达式<br>C-c s f             寻找文件<br>C-c s i             看看指定的文件被哪些文件include<br><br><br>简单配置<br><br>;;;; CC-mode..&nbsp; http://cc-mode.sourceforge.net/<br>(require 'cc-mode)<br>(c-set-offset 'inline-open 0)<br>(c-set-offset 'friend '-)<br>(c-set-offset 'substatement-open 0)<br><br><br>;;;;..C/C++......<br><br>(defun my-c-mode-common-hook()<br>&nbsp; (setq tab-width 4 indent-tabs-mode nil)<br>&nbsp; ;;; hungry-delete and auto-newline<br>&nbsp; (c-toggle-auto-hungry-state 1)<br>&nbsp; ;;....<br>&nbsp; (define-key c-mode-base-map [(control \`)] 'hs-toggle-hiding)<br>&nbsp; (define-key c-mode-base-map [(return)] 'newline-and-indent)<br>&nbsp; (define-key c-mode-base-map [(f7)] 'compile)<br>&nbsp; (define-key c-mode-base-map [(meta \`)] 'c-indent-command)<br>;;&nbsp; (define-key c-mode-base-map [(tab)] 'hippie-expand)<br>&nbsp; (define-key c-mode-base-map [(tab)] 'my-indent-or-complete)<br>&nbsp; (define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)<br><br>&nbsp;;;.....<br>&nbsp; (setq c-macro-shrink-window-flag t)<br>&nbsp; (setq c-macro-preprocessor "cpp")<br>&nbsp; (setq c-macro-cppflags " ")<br>&nbsp; (setq c-macro-prompt-flag t)<br>&nbsp; (setq hs-minor-mode t)<br>&nbsp; (setq abbrev-mode t)<br>&nbsp; (global-font-lock-mode t)<br>)<br>(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)<br><br>;;;;..C++......<br>(defun my-c++-mode-hook()<br>&nbsp; (setq tab-width 4 indent-tabs-mode nil)<br>&nbsp; (c-set-style "stroustrup")<br>;;&nbsp; (define-key c++-mode-map [f3] 'replace-regexp)<br>)<br><br>// 函数跳转 <br>(require 'xcscope)<br>(setq cscope-do-not-update-database t)<br><br><br>Emacs常用命令速查 <br><br>
&nbsp; &nbsp;&nbsp;&nbsp;现在我已经能够熟练使用这些命令了,基本上可以算一个初段的Emacser了,哈哈,总结一下,把这些命令打印出来贴在电脑上,不记得了再查查,从今以后尽量做到写代码和文档都用Emacs来完成.<br>
&nbsp;&nbsp;1）与文件操作有关的命令<br>
&nbsp;&nbsp;C-x C-f&nbsp; &nbsp; 查找文件并且在新缓冲区中打开<br>
&nbsp;&nbsp;C-x C-v&nbsp; &nbsp; 读入另一个文件替换掉用C-x C-f打开的文件<br>
&nbsp;&nbsp;C-x i&nbsp; &nbsp; 把文件插入到光标的当前位置<br>
&nbsp;&nbsp;C-x C-s&nbsp; &nbsp; 保存文件<br>
&nbsp;&nbsp;C-x C-w&nbsp; &nbsp; 把缓冲区内容写入一个文件<br>
&nbsp;&nbsp;C-x C-c&nbsp; &nbsp; 退出Emacs<br>
<br>
&nbsp;&nbsp;2）与光标移动操作有关的命令<br>
&nbsp;&nbsp;C-f&nbsp; &nbsp;&nbsp;&nbsp;光标前移一个字符（右）<br>
&nbsp;&nbsp;C-b&nbsp; &nbsp;&nbsp;&nbsp;光标后移一个字符（左）<br>
&nbsp;&nbsp;C-p&nbsp; &nbsp;&nbsp;&nbsp;光标前移一行（上）<br>
&nbsp;&nbsp;C-n&nbsp; &nbsp;&nbsp;&nbsp;光标后移一行（下）<br>
&nbsp;&nbsp;M-f&nbsp; &nbsp;&nbsp;&nbsp;前移一个单词<br>
&nbsp;&nbsp;M-b&nbsp; &nbsp;&nbsp;&nbsp;后移一个单词<br>
&nbsp;&nbsp;C-a&nbsp; &nbsp;&nbsp;&nbsp;移动到行首<br>
&nbsp;&nbsp;C-e&nbsp; &nbsp;&nbsp;&nbsp;移动到行尾<br>
&nbsp;&nbsp;M-e&nbsp; &nbsp;&nbsp;&nbsp;前移一个句子<br>
&nbsp;&nbsp;M-a&nbsp; &nbsp;&nbsp;&nbsp;后移一个句子<br>
&nbsp;&nbsp;M-}&nbsp; &nbsp;&nbsp;&nbsp;前移一个段落<br>
&nbsp;&nbsp;M-{&nbsp; &nbsp;&nbsp;&nbsp;后移一个段落<br>
&nbsp;&nbsp;C-v&nbsp; &nbsp;&nbsp;&nbsp;屏幕上卷一屏<br>
&nbsp;&nbsp;M-v&nbsp; &nbsp;&nbsp;&nbsp;屏幕下卷一屏<br>
&nbsp;&nbsp;C-x ]&nbsp; &nbsp; 前移一页<br>
&nbsp;&nbsp;C-x [&nbsp; &nbsp; 后移一页<br>
&nbsp;&nbsp;M-&lt;&nbsp; &nbsp;&nbsp;&nbsp;前移到文件头<br>
&nbsp;&nbsp;M-&gt;;&nbsp; &nbsp;&nbsp;&nbsp;后移到文件尾<br>
&nbsp;&nbsp;C-l&nbsp; &nbsp;&nbsp;&nbsp;重新绘制屏幕，当前行放在画面中心<br>
&nbsp;&nbsp;M-n 或者 C-u n&nbsp;&nbsp;重复执行n次后续命令<br>
&nbsp;&nbsp;按下M-x后在辅助输入区中输入"goto-line"跳到指定的行，输入"goto-char"跳到指定的字符<br>
<br>
&nbsp;&nbsp;3）与文件删除操作有关的命令<br>
&nbsp;&nbsp;C-d&nbsp; &nbsp;&nbsp;&nbsp;删除光标位置上的字符<br>
&nbsp;&nbsp;DEL&nbsp; &nbsp;&nbsp;&nbsp;删除光标前面的字符<br>
&nbsp;&nbsp;M-d&nbsp; &nbsp;&nbsp;&nbsp;删除光标后面的单词<br>
&nbsp;&nbsp;M-DEL&nbsp; &nbsp; 删除光标前面的单词<br>
&nbsp;&nbsp;C-k&nbsp; &nbsp;&nbsp;&nbsp;从光标位置删除到行尾<br>
&nbsp;&nbsp;M-k&nbsp; &nbsp;&nbsp;&nbsp;删除光标后面的句子<br>
&nbsp;&nbsp;C-x DEL&nbsp; &nbsp; 删除光标前面的句子<br>
&nbsp;&nbsp;C-y&nbsp; &nbsp;&nbsp;&nbsp;恢复被删除的文本或者粘贴最近删除或复制的文本<br>
&nbsp;&nbsp;C-w&nbsp; &nbsp;&nbsp;&nbsp;删除文件块<br>
&nbsp;&nbsp;按下M-x后在辅助输入区中输入"kill-paragraph"删除光标后面的段落，按下"backward-kill-paragraph"删除光标前面的段落<br>
<br>
&nbsp;&nbsp;4）与文本块操作有关的命令<br>
&nbsp;&nbsp;C-@&nbsp; &nbsp;&nbsp;&nbsp;标记文本块的开始（或结束）位置<br>
&nbsp;&nbsp;C-x C-x&nbsp; &nbsp; 互换插入点和文本标记的位置<br>
&nbsp;&nbsp;C-w 或 SHIFT-DEL 删除文本块<br>
&nbsp;&nbsp;M-w&nbsp; &nbsp;&nbsp;&nbsp;复制文本块<br>
&nbsp;&nbsp;M-h&nbsp; &nbsp;&nbsp;&nbsp;标记段落<br>
&nbsp;&nbsp;C-x C-p&nbsp; &nbsp; 标记页面<br>
&nbsp;&nbsp;C-x h&nbsp; &nbsp; 标记整个缓冲区<br>
<br>
&nbsp;&nbsp;5）与位置交换操作有关的命令<br>
&nbsp;&nbsp;C-t&nbsp; &nbsp;&nbsp;&nbsp;交换两个字符的位置<br>
&nbsp;&nbsp;M-t&nbsp; &nbsp;&nbsp;&nbsp;交换两个单词的位置<br>
&nbsp;&nbsp;C-x C-t&nbsp; &nbsp; 交换两个文本行的位置<br>
&nbsp;&nbsp;按下M-x后在辅助输入区中输入"transpose-sentences"交换两个句子的位置，按下"transpose-paragraph"交换两个段落的位置<br>
<br>
&nbsp;&nbsp;6）与改变字母大小写操作有关的命令<br>
&nbsp;&nbsp;M-c&nbsp; &nbsp;&nbsp;&nbsp;单词首字母改为大写<br>
&nbsp;&nbsp;M-u&nbsp; &nbsp;&nbsp;&nbsp;单词的字母全部改为大写<br>
&nbsp;&nbsp;M-l&nbsp; &nbsp;&nbsp;&nbsp;单词的字母全部改为小写<br>
<br>
&nbsp;&nbsp;7）与查找操作相关的命令<br>
&nbsp;&nbsp;C-s&nbsp; &nbsp;&nbsp;&nbsp;向前递增查找<br>
&nbsp;&nbsp;C-r&nbsp; &nbsp;&nbsp;&nbsp;向后递增查找<br>
&nbsp;&nbsp;C-s C-w&nbsp; &nbsp; 开始递增查找，把光标位置的单词做查找字符串<br>
&nbsp;&nbsp;C-s C-y&nbsp; &nbsp; 开始递增查找，把光标位置到行尾之间的文本做查找字符串<br>
&nbsp;&nbsp;C-s return searchstring return&nbsp;&nbsp;向前开始非递增查找操作<br>
&nbsp;&nbsp;C-r return searchstring return&nbsp;&nbsp;向后开始非递增查找操作<br>
&nbsp;&nbsp;C-s return C-w&nbsp;&nbsp;向前开始单词查找（不受换行符、空格、标点符号影响）<br>
&nbsp;&nbsp;C-r return C-w&nbsp;&nbsp;向后开始单词查找（不受换行符、空格、标点符号影响）<br>
<br>
&nbsp;&nbsp;8) 与使用编辑缓冲区和窗口有关的命令<br>
&nbsp;&nbsp;C-x b&nbsp; &nbsp; 如果输入一个新的文件名则新建一个文件并且编辑,否则打开该文件<br>
&nbsp;&nbsp;C-x s&nbsp; &nbsp; 保存全部缓冲区<br>
&nbsp;&nbsp;C-x b&nbsp; &nbsp; 删除缓冲区<br>
&nbsp;&nbsp;M-x rename-buffer 重命名当前缓冲区<br>
&nbsp;&nbsp;C-x C-q&nbsp; &nbsp; 把当前编辑缓冲区设置为只读属性<br>
&nbsp;&nbsp;C-x 0&nbsp; &nbsp; 删除当前所在的窗口<br>
&nbsp;&nbsp;C-x 1&nbsp; &nbsp; 当前缓冲区满屏显示<br>
&nbsp;&nbsp;C-x 2&nbsp; &nbsp; 创建上下排列的窗口<br>
&nbsp;&nbsp;C-x 3&nbsp; &nbsp; 创建左右排列的窗口<br>
&nbsp;&nbsp;C-x o&nbsp; &nbsp; 在窗口之间移动<br>
<br><br></pre>
</pre>
</div>
<br><img src ="http://www.cnitblog.com/schkui/aggbug/27785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2007-05-30 15:52 <a href="http://www.cnitblog.com/schkui/archive/2007/05/30/27785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>例解 autoconf 和 automake 生成 Makefile 文件</title><link>http://www.cnitblog.com/schkui/archive/2007/04/17/25821.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Tue, 17 Apr 2007 05:36:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/04/17/25821.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/25821.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/04/17/25821.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/25821.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/25821.html</trackback:ping><description><![CDATA[<img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="10">
<table class="no-print" align="right" border="0" cellpadding="0" cellspacing="0" width="160">
    <tbody>
        <tr>
            <td width="10"><img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="10"></td>
            <td>
            <table border="0" cellpadding="0" cellspacing="0" width="150">
                <tbody>
                    <tr>
                        <td class="v14-header-1-small">文档选项</td>
                    </tr>
                </tbody>
            </table>
            <table class="v14-gray-table-border" border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td class="no-padding" width="150"><img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="8"><input value="本文介绍了在 linux 系统中，通过 gnu autoconf 和 automake 生成 makefile 的方法。主要探讨了生成 makefile 的来龙去脉及其机理，接着详细介绍了配置 configure.in 的方法及其规则。" name="body" type="hidden"><input name="subject" value="例解 autoconf 和 automake 生成 makefile 文件" type="hidden"><input name="lang" value="cn" type="hidden"><noscript>
                        <tr
                        valign="top">
                        <td width="8"><img alt="" height="1" width="8"
                        src="//www.ibm.com/i/c.gif"/></td>
                        <td width="16"><img alt="" width="16"
                        height="16" src="//www.ibm.com/i/c.gif"/></td>
                        <td class="small"
                        width="122">
                        <p><span class="ast">未显示需要 JavaScript
                        的文档选项</span></p>
                        </td>
                    </tr>
                    </noscript>
                    <table border="0" cellpadding="0" cellspacing="0" width="143">
                        <form action="https://www.ibm.com/developerworks/secure/email-it.jsp" name="email">
                        </form>
                        <script language="JavaScript" type="text/javascript">
                        <!--
                        document.write('
                        <tr valign="top">
                            <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td>
                            <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td>
                            <td width="122">
                            <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                            </td>
                        </tr>
                        ');
                        //-->
                        </script>
                        <tbody>
                            <tr valign="top">
                                <td width="8"><img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="8"></td>
                                <td width="16"><img  src="http://www.ibm.com/i/v14/icons/em.gif" alt="将此页作为电子邮件发送" height="16" vspace="3" width="16"></td>
                                <td width="122">
                                <p><a  href="javascript:document.email.submit();" class="smallplainlink"><strong>将此页作为电子邮件发送</strong></a></p>
                                </td>
                            </tr>
                            <tr valign="top">
                                <td width="8"><img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="8"></td>
                                <td width="16"><img  src="http://www.ibm.com/i/v14/icons/dn.gif" alt="" border="0" height="16" vspace="3" width="16"></td>
                                <td width="122">
                                <p><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#download" class="smallplainlink"><strong>样例代码</strong></a></p>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    </td>
                </tr>
            </tbody>
        </table>
        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- 03/20/06 updated by gretchen -->
        <br>
        <table border="0" cellpadding="0" cellspacing="0" width="150">
            <tbody>
                <tr>
                    <td class="v14-header-2-small">拓展 Tomcat 应用</td>
                </tr>
            </tbody>
        </table>
        <table class="v14-gray-table-border" border="0" cellpadding="0" cellspacing="0">
            <tbody>
                <tr>
                    <td class="no-padding" width="150">
                    <table border="0" cellpadding="0" cellspacing="0" width="143">
                        <tbody>
                            <tr valign="top">
                                <td width="8"><img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="8"></td>
                                <td><img  src="http://www.ibm.com/i/v14/icons/fw_bold.gif" alt="" border="0" height="16" vspace="3" width="16"></td>
                                <td width="125">
                                <p><a  href="http://www.ibm.com/developerworks/cn/kickstart/webserver.html?S_TACT=105AGX52&amp;S_CMP=simpleart" class="smallplainlink">下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1</a>
                                </p>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    </td>
                </tr>
            </tbody>
        </table>
        <!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br></td>
    </tr>
</tbody>
</table>
<p>级别: 初级</p>
<p><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#author">杨 小华</a> (<a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#110;&#111;&#114;&#109;&#97;&#108;&#110;&#111;&#116;&#101;&#98;&#111;&#111;&#107;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#37;&#69;&#52;&#37;&#66;&#69;&#37;&#56;&#66;&#37;&#69;&#56;&#37;&#65;&#55;&#37;&#65;&#51;&#37;&#50;&#48;&#97;&#117;&#116;&#111;&#99;&#111;&#110;&#102;&#37;&#50;&#48;&#37;&#69;&#53;&#37;&#57;&#50;&#37;&#56;&#67;&#37;&#50;&#48;&#97;&#117;&#116;&#111;&#109;&#97;&#107;&#101;&#37;&#50;&#48;&#37;&#69;&#55;&#37;&#57;&#52;&#37;&#57;&#70;&#37;&#69;&#54;&#37;&#56;&#56;&#37;&#57;&#48;&#37;&#50;&#48;&#77;&#97;&#107;&#101;&#102;&#105;&#108;&#101;&#37;&#50;&#48;&#37;&#69;&#54;&#37;&#57;&#54;&#37;&#56;&#55;&#37;&#69;&#52;&#37;&#66;&#66;&#37;&#66;&#54;">normalnotebook@126.com</a>), Linux 内核研究员<br><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#author">苏 春艳</a>, 在读研究生<br></p>
<p>2006 年  9 月  21 日</p>
<blockquote>本文介绍了在 linux 系统中，通过 Gnu autoconf 和 automake 生成 Makefile 的方法。主要探讨了生成 Makefile 的来龙去脉及其机理，接着详细介绍了配置 Configure.in 的方法及其规则。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
<!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><a name="N1005C"><span class="atitle">引子</span></a></p>
<p>无论是在Linux还是在Unix环境中，make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件，我们都经常要用到
make或 make
install。利用make工具，我们可以将大型的开发项目分解成为多个更易于管理的模块，对于一个包括几百个源文件的应用程序，使用make和
makefile工具就可以轻而易举的理顺各个源文件之间纷繁复杂的相互关系。</p>
<p>但是如果通过查阅make的帮助文档来手工编写Makefile,对任何程序员都是一场挑战。幸而有GNU 提供的Autoconf及Automake这两套工具使得编写makefile不再是一个难题。</p>
<p>本文将介绍如何利用 GNU Autoconf 及 Automake 这两套工具来协助我们自动产生
Makefile文件，并且让开发出来的软件可以像大多数源码包那样，只需"./configure", "make","make install"
就可以把程序安装到系统中。</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%"><br><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="6" width="8"></td>
        </tr>
    </tbody>
</table>
<table class="no-print" align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%"><br>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img  src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16"><br></td>
                        <td align="right" valign="top"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name="N1006B"><span class="atitle">模拟需求</span></a></p>
<p>假设源文件按如下目录存放，如图1所示，运用autoconf和automake生成makefile文件。</p>
<br><a name="N10076"><strong>图 1文件目录结构</strong></a><br>
<img  src="http://www.ibm.com/developerworks/cn/linux/l-makefile/images/image001.jpg" alt="图 1文件目录结构" border="0" height="190" width="217">
<br>
<p>假设src是我们源文件目录，include目录存放其他库的头文件，lib目录存放用到的库文件，然后开始按模块存放，每个模块都有一个对应的目
录，模块下再分子模块，如apple、orange。每个子目录下又分core，include，shell三个目录，其中core和shell目录存
放.c文件，include的存放.h文件，其他类似。</p>
<p>样例程序功能：基于多线程的数据读写保护（联系作者获取整个autoconf和automake生成的Makefile工程和源码，E-mail：<a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#110;&#111;&#114;&#109;&#97;&#108;&#110;&#111;&#116;&#101;&#98;&#111;&#111;&#107;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;">normalnotebook@126.com</a>）。</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%"><br><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="6" width="8"></td>
        </tr>
    </tbody>
</table>
<table class="no-print" align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%"><br>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img  src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16"><br></td>
                        <td align="right" valign="top"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name="N10090"><span class="atitle">工具简介</span></a></p>
<p>所必须的软件：autoconf/automake/m4/perl/libtool（其中libtool非必须）。</p>
<p>autoconf是一个用于生成可以自动地配置软件源码包，用以适应多种UNIX类系统的shell脚本工具，其中autoconf需要用到
m4，便于生成脚本。automake是一个从Makefile.am文件自动生成Makefile.in的工具。为了生成Makefile.in，
automake还需用到perl，由于automake创建的发布完全遵循GNU标准，所以在创建中不需要perl。libtool是一款方便生成各种
程序库的工具。</p>
<p>目前automake支持三种目录层次：flat、shallow和deep。</p>
<p>1)	flat指的是所有文件都位于同一个目录中。</p>
<p>就是所有源文件、头文件以及其他库文件都位于当前目录中，且没有子目录。Termutils就是这一类。</p>
<p>2)	shallow指的是主要的源代码都储存在顶层目录，其他各个部分则储存在子目录中。</p>
<p>就是主要源文件在当前目录中，而其它一些实现各部分功能的源文件位于各自不同的目录。automake本身就是这一类。</p>
<p>3)	deep指的是所有源代码都被储存在子目录中；顶层目录主要包含配置信息。</p>
<p>就是所有源文件及自己写的头文件位于当前目录的一个子目录中，而当前目录里没有任何源文件。 GNU cpio和GNU tar就是这一类。</p>
<p>flat类型是最简单的，deep类型是最复杂的。不难看出，我们的模拟需求正是基于第三类deep型，也就是说我们要做挑战性的事情：)。注：我们的测试程序是基于多线程的简单程序。</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%"><br><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="6" width="8"></td>
        </tr>
    </tbody>
</table>
<table class="no-print" align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%"><br>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img  src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16"><br></td>
                        <td align="right" valign="top"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name="N100B4"><span class="atitle">生成 Makefile 的来龙去脉</span></a></p>
<p>首先进入 project 目录，在该目录下运行一系列命令，创建和修改几个文件，就可以生成符合该平台的Makefile文件，操作过程如下：</p>
<p>1)	运行autoscan命令</p>
<p>2)	将configure.scan 文件重命名为configure.in，并修改configure.in文件</p>
<p>3)	在project目录下新建Makefile.am文件，并在core和shell目录下也新建makefile.am文件</p>
<p>4)	在project目录下新建NEWS、 README、 ChangeLog 、AUTHORS文件</p>
<p>5)	将/usr/share/automake-1.X/目录下的depcomp和complie文件拷贝到本目录下</p>
<p>6)	运行aclocal命令</p>
<p>7)	运行autoconf命令</p>
<p>8)	运行automake -a命令</p>
<p>9)	运行./confiugre脚本</p>
<p>可以通过图2看出产生Makefile的流程，如图所示：</p>
<br><a name="N100DD"><strong>图 2生成Makefile流程图</strong></a><br>
<img  src="http://www.ibm.com/developerworks/cn/linux/l-makefile/images/image002.gif" alt="图 2生成makefile流程图" border="0" height="338" width="468">
<br>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%"><br><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="6" width="8"></td>
        </tr>
    </tbody>
</table>
<table class="no-print" align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%"><br>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img  src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16"><br></td>
                        <td align="right" valign="top"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name="N100ED"><span class="atitle">Configure.in的八股文</span></a></p>
<p>当我们利用autoscan工具生成confiugre.scan文件时，我们需要将confiugre.scan重命名为confiugre.in文件。confiugre.in调用一系列autoconf宏来测试程序需要的或用到的特性是否存在，以及这些特性的功能。</p>
<p>下面我们就来目睹一下confiugre.scan的庐山真面目：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode"># Process this file with autoconf to produce a configure script.<br>AC_PREREQ(2.59)<br>AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)<br>AC_CONFIG_SRCDIR([config.h.in])<br>AC_CONFIG_HEADER([config.h])<br># Checks for programs.<br>AC_PROG_CC<br># Checks for libraries.<br># FIXME: Replace `main' with a function in `-lpthread':<br>AC_CHECK_LIB([pthread], [main])<br># Checks for header files.<br># Checks for typedefs, structures, and compiler characteristics.<br># Checks for library functions.<br>AC_OUTPUT<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>每个configure.scan文件都是以AC_INIT开头，以AC_OUTPUT结束。我们不难从文件中看出confiugre.in文件的一般布局：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">AC_INIT<br> 测试程序<br> 测试函数库<br> 测试头文件<br> 测试类型定义<br> 测试结构<br> 测试编译器特性<br> 测试库函数<br> 测试系统调用<br>AC_OUTPUT<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>上面的调用次序只是建议性质的，但我们还是强烈建议不要随意改变对宏调用的次序。</p>
<p>现在就开始修改该文件：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">$mv configure.scan configure.in<br>$vim configure.in<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>修改后的结果如下：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">		<br>#                                -*- Autoconf -*-<br># Process this file with autoconf to produce a configure script.<br><br>AC_PREREQ(2.59)<br>AC_INIT(test, 1.0, normalnotebook@126.com)<br>AC_CONFIG_SRCDIR([src/ModuleA/apple/core/test.c])<br>AM_CONFIG_HEADER(config.h)<br>AM_INIT_AUTOMAKE(test,1.0)<br><br># Checks for programs.<br>AC_PROG_CC<br># Checks for libraries.<br># FIXME: Replace `main' with a function in `-lpthread':<br>AC_CHECK_LIB([pthread], [pthread_rwlock_init])<br>AC_PROG_RANLIB<br># Checks for header files.<br># Checks for typedefs, structures, and compiler characteristics.<br># Checks for library functions.<br>AC_OUTPUT([Makefile<br>		src/lib/Makefile<br>		src/ModuleA/apple/core/Makefile<br>		src/ModuleA/apple/shell/Makefile<br>		])<br>		</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>其中要将AC_CONFIG_HEADER([config.h])修改为：AM_CONFIG_HEADER(config.h),
并加入AM_INIT_AUTOMAKE(test,1.0)。由于我们的测试程序是基于多线程的程序，所以要加入AC_PROG_RANLIB，不然运行automake命令时会出错。在AC_OUTPUT输入要创建的Makefile文件名。</p>
<p>由于我们在程序中使用了读写锁，所以需要对库文件进行检查，即AC_CHECK_LIB([pthread], [main])，该宏的含义如下：</p>
<br>
<img  src="http://www.ibm.com/developerworks/cn/linux/l-makefile/images/table1.gif" alt="" border="0" height="166" width="537">
<br>
<p>其中，LIBS是link的一个选项，详细请参看后续的Makefile文件。由于我们在程序中使用了读写锁，所以我们测试pthread库中是否存在pthread_rwlock_init函数。</p>
<p>由于我们是基于deep类型来创建makefile文件，所以我们需要在四处创建Makefile文件。即：project目录下，lib目录下，core和shell目录下。	</p>
<p>Autoconf提供了很多内置宏来做相关的检测，限于篇幅关系，我们在这里对其他宏不做详细的解释，具体请参看参考文献1和参考文献2，也可参看autoconf信息页。</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%"><br><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="6" width="8"></td>
        </tr>
    </tbody>
</table>
<table class="no-print" align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%"><br>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img  src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16"><br></td>
                        <td align="right" valign="top"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name="N10149"><span class="atitle">实战Makefile.am</span></a></p>
<p>Makefile.am是一种比Makefile更高层次的规则。只需指定要生成什么目标，它由什么源文件生成，要安装到什么目录等构成。</p>
<p>表一列出了可执行文件、静态库、头文件和数据文件，四种书写Makefile.am文件个一般格式。</p>
<br><a name="N10157"><strong>表 1Makefile.am一般格式</strong></a><br>
<img  src="http://www.ibm.com/developerworks/cn/linux/l-makefile/images/table2.gif" alt="表 1makefile.am一般格式" border="0" height="351" width="522">
<br>
<p>对于可执行文件和静态库类型，如果只想编译，不想安装到系统中，可以用noinst_PROGRAMS代替bin_PROGRAMS，noinst_LIBRARIES代替lib_LIBRARIES。</p>
<p>Makefile.am还提供了一些全局变量供所有的目标体使用：</p>
<br><a name="N1016F"><strong>表 2 Makefile.am中可用的全局变量</strong></a><br>
<img  src="http://www.ibm.com/developerworks/cn/linux/l-makefile/images/table3.gif" alt="表 2 makefile.am中可用的全局变量" border="0" height="221" width="523">
<br>
<p>在Makefile.am中尽量使用相对路径，系统预定义了两个基本路径：</p>
<br><a name="N10184"><strong>表 3Makefile.am中可用的路径变量</strong></a><br>
<img  src="http://www.ibm.com/developerworks/cn/linux/l-makefile/images/table4.gif" alt="表 3makefile.am中可用的路径变量" border="0" height="112" width="522">
<br>
<p>在上文中我们提到过安装路径，automake设置了默认的安装路径：</p>
<p>1)	标准安装路径</p>
<p>默认安装路径为：$(prefix) = /usr/local，可以通过./configure --prefix=&lt;new_path&gt;的方法来覆盖。</p>
<p>其它的预定义目录还包括：bindir = $(prefix)/bin, libdir = $(prefix)/lib, datadir = $(prefix)/share, sysconfdir = $(prefix)/etc等等。</p>
<p>2)	定义一个新的安装路径</p>
<p>比如test, 可定义testdir = $(prefix)/test,  然后test_DATA =test1 test2，则test1，test2会作为数据文件安装到$(prefix)/ /test目录下。</p>
<p>我们首先需要在工程顶层目录下（即project/）创建一个Makefile.am来指明包含的子目录：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">SUBDIRS=src/lib src/ModuleA/apple/shell src/ModuleA/apple/core <br>CURRENTPATH=$(shell /bin/pwd)<br>INCLUDES=-I$(CURRENTPATH)/src/include -I$(CURRENTPATH)/src/ModuleA/apple/include <br>export INCLUDES<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>由于每个源文件都会用到相同的头文件，所以我们在最顶层的Makefile.am中包含了编译源文件时所用到的头文件，并导出，见蓝色部分代码。</p>
<p>我们将lib目录下的swap.c文件编译成libswap.a文件，被apple/shell/apple.c文件调用，那么lib目录下的Makefile.am如下所示：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">noinst_LIBRARIES=libswap.a<br>libswap_a_SOURCES=swap.c<br>INCLUDES=-I$(top_srcdir)/src/includ<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>细心的读者可能就会问：怎么表1中给出的是bin_LIBRARIES，而这里是noinst_LIBRARIES？这是因为如果只想编译，而不想
安装到系统中，就用noinst_LIBRARIES代替bin_LIBRARIES，对于可执行文件就用noinst_PROGRAMS代替
bin_PROGRAMS。对于安装的情况，库将会安装到$(prefix)/lib目录下，可执行文件将会安装到${prefix}/bin。如果想安
装该库，则Makefile.am示例如下：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">bin_LIBRARIES=libswap.a<br>libswap_a_SOURCES=swap.c<br>INCLUDES=-I$(top_srcdir)/src/include<br>swapincludedir=$(includedir)/swap<br>swapinclude_HEADERS=$(top_srcdir)/src/include/swap.h<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>最后两行的意思是将swap.h安装到${prefix}/include /swap目录下。</p>
<p>接下来，对于可执行文件类型的情况，我们将讨论如何写Makefile.am？对于编译apple/core目录下的文件，我们写成的Makefile.am如下所示：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">noinst_PROGRAMS=test<br>test_SOURCES=test.c <br>test_LDADD=$(top_srcdir)/src/ModuleA/apple/shell/apple.o $(top_srcdir)/src/lib/libswap.a <br>test_LDFLAGS=-D_GNU_SOURCE<br>DEFS+=-D_GNU_SOURCE<br>#LIBS=-lpthread<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>由于我们的test.c文件在链接时，需要apple.o和
libswap.a文件，所以我们需要在test_LDADD中包含这两个文件。对于Linux下的信号量/读写锁文件进行编译，需要在编译选项中指明-
D_GNU_SOURCE。所以在test_LDFLAGS中指明。而test_LDFLAGS只是链接时的选项，编译时同样需要指明该选项，所以需要
DEFS来指明编译选项，由于DEFS已经有初始值，所以这里用+=的形式指明。从这里可以看出，Makefile.am中的语法与Makefile的语
法一致，也可以采用条件表达式。如果你的程序还包含其他的库，除了用AC_CHECK_LIB宏来指明外，还可以用LIBS来指明。</p>
<p>如果你只想编译某一个文件，那么Makefile.am如何写呢？这个文件也很简单，写法跟可执行文件的差不多，如下例所示：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">noinst_PROGRAMS=apple<br>apple_SOURCES=apple.c<br>DEFS+=-D_GNU_SOURCE<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>我们这里只是欺骗automake，假装要生成apple文件，让它为我们生成依赖关系和执行命令。所以当你运行完automake命令后，然后修改apple/shell/下的Makefile.in文件，直接将LINK语句删除，即：</p>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">&#8230;&#8230;.<br>clean-noinstPROGRAMS:<br>	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)<br>apple$(EXEEXT): $(apple_OBJECTS) $(apple_DEPENDENCIES) <br>	@rm -f apple$(EXEEXT)<br>#$(LINK) $(apple_LDFLAGS) $(apple_OBJECTS) $(apple_LDADD) $(LIBS)<br>&#8230;&#8230;.<br></pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>通过上述处理，就可以达到我们的目的。从图1中不难看出为什么要修改Makefile.in的原因，而不是修改其他的文件。</p>
<br><br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%"><br><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="6" width="8"></td>
        </tr>
    </tbody>
</table>
<table class="no-print" align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%"><br>
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img  src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16"><br></td>
                        <td align="right" valign="top"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><span class="atitle"><a name="download">下载</a></span></p>
<table class="data-table-1" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <th scope="col">名字</th><th scope="col" align="right">大小</th><th scope="col">下载方法</th>
        </tr>
        <tr>
            <td nowrap="nowrap">project.rar</td>
            <td align="right" nowrap="nowrap"><br></td>
            <td nowrap="nowrap"><a  href="http://www.ibm.com/developerworks/cn/linux/l-makefile/project.rar" class="fbox"><strong>HTTP</strong></a></td>
        </tr>
    </tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr valign="top">
            <td colspan="5"><img  src="http://www.ibm.com/i/c.gif" alt="" border="0" height="12" width="12"></td>
        </tr>
        <tr>
            <td><img  src="http://www.ibm.com/i/v14/icons/fw.gif" alt="" height="16" width="16"></td>
            <td><a  href="http://www.ibm.com/developerworks/cn/whichmethod.html" class="fbox">关于下载方法的信息</a></td>
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="1" width="50"></td>
            <td><img  src="http://www.ibm.com/i/v14/icons/sout.gif" alt="" height="16" width="16"></td>
            <td><a  href="http://www.adobe.com/products/acrobat/readstep2.html" class="fbox">Get Adobe&#174; Reader&#174;</a></td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name="resources"><span class="atitle">参考资料 </span></a></p>
<ol>
    <li>Kurt Wall，张辉译 《GNU/Linux编程指南》 清华大学出版社</li>
    <li>Robert Mecklenburg，《GNU Make项目管理（第三版）》 东南大学出版社 2006</li>
    <li><a  href="http://www.cngnu.org/technology/index.html">http://www.cngnu.org/technology/index.html</a></li>
</ol>
<br><br>
<p><a name="author"><span class="atitle">作者简介</span></a></p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td colspan="3"><img  src="http://www.ibm.com/i/c.gif" alt="" height="5" width="100%"></td>
        </tr>
        <tr align="left" valign="top">
            <td><br></td>
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="5" width="4"></td>
            <td width="100%">
            <p>杨小华，目前从事 Linux 内核方面的研究，喜欢捣鼓 Linux 系统，对 Linux 中断系统比较了解。可以通过 <a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#110;&#111;&#114;&#109;&#97;&#108;&#110;&#111;&#116;&#101;&#98;&#111;&#111;&#107;&#64;&#49;&#50;&#54;&#46;&#99;&#111;&#109;&#63;&#99;&#99;&#61;">normalnotebook@126.com</a>与他取得联系。</p>
            </td>
        </tr>
    </tbody>
</table>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td colspan="3"><img  src="http://www.ibm.com/i/c.gif" alt="" height="5" width="100%"></td>
        </tr>
        <tr align="left" valign="top">
            <td><br></td>
            <td><img  src="http://www.ibm.com/i/c.gif" alt="" height="5" width="4"></td>
            <td width="100%">
            <p>苏春艳：在读研究生，主要在Linux系统下从事嵌入式开发。</p>
            </td>
        </tr>
    </tbody>
</table><img src ="http://www.cnitblog.com/schkui/aggbug/25821.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2007-04-17 13:36 <a href="http://www.cnitblog.com/schkui/archive/2007/04/17/25821.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 下 Apache 与 Tomcat 整合的简单方法</title><link>http://www.cnitblog.com/schkui/archive/2006/11/29/19714.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Wed, 29 Nov 2006 04:21:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/11/29/19714.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/19714.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/11/29/19714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/19714.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/19714.html</trackback:ping><description><![CDATA[
		<font class="f14" id="zoom">
				<p>把安装过程大概做个说明记录，一是有个总结，二是希望能帮到其他的朋友，有不恰当的地方希望大家指正，呵呵<br />安装Redhat AS 
            3.0就不多说了，我是自定义安装，把以后需要的工具如gcc等都装上了，省的以后用的时候没有还得装，麻烦，呵呵，你就随便了</p>
				<p>
						<br />安装j2sdk-1_4_2_02-linux-i586-rpm.bin（或其他版本都ok）<br />下载后双击安装<br />______________________________________________________</p>
				<p>配置环境变量<br />编辑/etc/profile 加入下面句：<br />PATH=/usr/j2se/bin 
            （改为你安装j2sdk的路径）<br />JAVA_HOME=/usr/j2se 
            （改为你安装j2sdk的路径）<br />CLASSPATH=/usr/j2se/lib/tools.jar:/usr/j2se/lib/dt.jar 
            （改为你安装j2sdk的路径）<br />export PATH JAVA_HOME CLASSPATH</p>
				<p>重新启动使之生效<br />_________________________________________________________________<br />Tomcat 
            5.0.25</p>
				<p>在<a href="http://www.apache.org/">http://www.apache.org/</a>下载得到jakart...t-5.0.25.tar.gz<br />#gunzip 
            jakarta-tomcat-5.0.25.tar.gz<br />#tar xvf 
            jakarta-tomcat-5.0.25.tar<br />#mv jakarta-tomcat-5.0.25 
            /usr/local/tomcat5.0.25<br />#cd 
            /usr/local/tomcat5.0.25/bin<br />#./catalina.sh start</p>
				<p>然后测试 <a href="http://localhost:8080/">http://localhost:8080/</a> 
            看到那个猫了吧，恭喜你tomcat安装ok</p>
				<p>_____________________________________________________________________</p>
				<p>安装apache2.0.50<br />估计用到的工具有：gcc,automake,autoconfig;libtools,m4 
            大家可以去下载rpm包安装就行了，别忘了写人环境变量噢 :-P</p>
				<p>到<a href="http://www.apache.org/">http://www.apache.org/</a>下载后</p>
				<p>gunzip httpd-2.0.50.tar.gz<br />tar xvf httpd-2.0.50.tar<br />cd 
            httpd-2.0.50/bin<br />./configure -prefix=/usr/local/apache2 
            -enable-so 
            (可改为你自己的目录；-enable-so用于加载connector，不可省略，你还可以加上你自己的其他模块)<br />make<br />make 
            install<br />cd /usr/local/apache2/conf<br />vi 
            httpd.conf<br />更改：servername 你的机器ip或域名<br />group nobody<br />listen 
            yourip:80 （apache2以后把port已经改成了listen）</p>
				<p>保存后，cd ../bin<br />./apachectl start</p>
				<p>测试：<a href="http://localhost/">http://localhost/</a> 
            看到apache的欢迎界面了吧，ok</p>
				<p>_____________________________________________________________________________________</p>
				<p>整合apache2与tomcat5.0.25</p>
				<p>用连接器jakarta-tomcat-connectors-jk2-src-current.tar.gz（就是jk2），大家可到<a href="http://jakarta.apache.org/site/sourceindex.cgi">http://jakarta.apache.org/site/sourceindex.cgi</a>下载</p>
				<p>gunzip jakarta-tomcat-connectors-jk2-src-current.tar.gz<br />tar 
            xvf jakarta-tomcat-connectors-jk2-src-current.tar<br />cd 
            jakarta-tomcat-connectors-jk2-src-current/jk/native2<br />./configure 
            --with-apxs2=/usr/local/apache2/bin/apxs 
            (注意改为你的apache安装目录)<br />make<br />cd 
            ../build/jk2/apache2<br />/usr/local/apache2/bin/apxs -n jk2 -i 
            mod_jk2.so<br />现在大家可以看到mod_jk2.so文件已经在你的apache/modules/ 中了</p>
				<p>编辑apache/conf/httpd.conf<br />LoadModule jk2_module 
            modules/mod_jk2.so 保存</p>
				<p>在apache/conf/中新建文件workers2.properties，内容为下（注意其中目录要改为你的目录噢）：</p>
				<p>[shm]<br />file=/usr/local/apache2/logs/shm.file<br />size=1048576<br /># 
            Example socket channel， override port and 
            host.<br />[channel.socket:localhost:8009]<br />port=8009<br />host=127.0.0.1<br /># 
            define the 
            worker<br />[ajp13:localhost:8009]<br />channel=channel.socket:localhost:8009<br /># 
            Uri mapping<br />[uri:/*]<br />worker=ajp13:localhost:8009</p>
				<p>保存后，就快大功告成啦，呵呵</p>
				<p>cd apache2/bin<br />./apachectl start</p>
				<p>测试：<a href="http://localhost/">http://localhost/</a> 
            大家是不是看到了那个猫猫的界面啊，恭喜恭喜，整合成功咯！！！(可别忘了启动tomcat)</p>
		</font>
<img src ="http://www.cnitblog.com/schkui/aggbug/19714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-11-29 12:21 <a href="http://www.cnitblog.com/schkui/archive/2006/11/29/19714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 2.4 Packet Filtering HOWTO 简体中文版</title><link>http://www.cnitblog.com/schkui/archive/2006/11/01/18738.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Wed, 01 Nov 2006 09:49:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/11/01/18738.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/18738.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/11/01/18738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/18738.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/18738.html</trackback:ping><description><![CDATA[
		<span>Rusty Russell, mailing list netfilter@lists.samba.org<br />
$Revision: 1.3 $ $Date: 2002/06/05 13:21:56 $<br />
简体中文：<a href="mailto:netsnake@963.net">洋鬼鬼·NetSnake</a><br />
感谢 网中人<a href="mailto:netmanforever@yahoo.com">netmanforever@yahoo.com</a> 提供的繁体参照</span>
		<br />
		<span> 此文档描述在Linux2.4 内核中，如何使用iptables过滤不正确的包<br />（译者：Packet在很多专业书籍中译为分组，此处根据大部分人的习惯，仍译为包）</span>
		<br />
		<table>
				<tbody>
						<tr>
								<td class="i0">1. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#intro">简介</a></td>
						</tr>
						<tr>
								<td class="i0">2. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#officer">官方站点及邮件列表</a></td>
						</tr>
						<tr>
								<td class="i0">3. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#whatis">那么，什么是Packet Filter？</a></td>
						</tr>
						<tr>
								<td>3.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#whyineed">我为什么需要Packet Filter？</a></td>
						</tr>
						<tr>
								<td>3.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#howto">如何在Linux下进行包过滤？</a></td>
						</tr>
						<tr>
								<td class="i2">3.2.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#iptables">iptables</a></td>
						</tr>
						<tr>
								<td class="i2">3.2.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#permanent">创建永久性规则</a></td>
						</tr>
						<tr>
								<td class="i0">4. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#whoareyou">你算老几，凭什么玩弄我的内核？</a></td>
						</tr>
						<tr>
								<td class="i0">5. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#fast">Rusty的真正的包过滤快速指南</a></td>
						</tr>
						<tr>
								<td class="i0">6. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#howpass">包是如何穿过过滤器的</a></td>
						</tr>
						<tr>
								<td class="i0">7. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#useiptables">使用iptables</a></td>
						</tr>
						<tr>
								<td>7.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#afterboot">当计算机启动后你会看到的</a></td>
						</tr>
						<tr>
								<td>7.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#justrule">对单个规则的操作</a></td>
						</tr>
						<tr>
								<td>7.3 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#filters">过滤规格</a></td>
						</tr>
						<tr>
								<td class="i2">7.3.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#sdip">指定源和目的IP地址</a></td>
						</tr>
						<tr>
								<td class="i2">7.3.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#inversions">反向指定</a></td>
						</tr>
						<tr>
								<td class="i2">7.3.3 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#protocols">协议指定</a></td>
						</tr>
						<tr>
								<td class="i2">7.3.4 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#interfaces">接口指定</a></td>
						</tr>
						<tr>
								<td class="i2">7.3.5 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#frags">分片指定</a></td>
						</tr>
						<tr>
								<td class="i2">7.3.6 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#newmatch">iptables扩展：新的匹配</a></td>
						</tr>
						<tr>
								<td class="i3">7.3.6.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#etcp">TCP 扩展</a></td>
						</tr>
						<tr>
								<td style="text-indent: 88px;">7.3.6.1.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#tcpflag">TCP标志的解释</a></td>
						</tr>
						<tr>
								<td class="i3">7.3.6.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#eudp">UDP 扩展</a></td>
						</tr>
						<tr>
								<td class="i3">7.3.6.3 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#eicmp">ICMP扩展</a></td>
						</tr>
						<tr>
								<td class="i3">7.3.6.4 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#eother">其他匹配的扩展</a></td>
						</tr>
						<tr>
								<td class="i3">7.3.6.5 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#status">状态匹配</a></td>
						</tr>
						<tr>
								<td>7.4 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#dests">目标规格</a></td>
						</tr>
						<tr>
								<td class="i2">7.4.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#udc">用户定义链</a></td>
						</tr>
						<tr>
								<td class="i2">7.4.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#newtarget">iptables扩展：新目标</a></td>
						</tr>
						<tr>
								<td class="i2">7.4.3 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#sbuilt">特殊的内建目标</a></td>
						</tr>
						<tr>
								<td>7.5 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#wholechain">对整个链进行操作</a></td>
						</tr>
						<tr>
								<td class="i2">7.5.1 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#createchain">创建新链</a></td>
						</tr>
						<tr>
								<td class="i2">7.5.2 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#deletechain">删除链</a></td>
						</tr>
						<tr>
								<td class="i2">7.5.3 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#flushchain">清空一个链</a></td>
						</tr>
						<tr>
								<td class="i2">7.5.4 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#listchain">对链进行列表</a></td>
						</tr>
						<tr>
								<td class="i2">7.5.5 <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#zerocounter">重置（清零）计数器</a></td>
						</tr>
						<tr>
								<td class="i2">7.5.6 <a href="http://cmpp.linuxforum.net/NetSnake/setpolicy">设置原则（默认规则）</a></td>
						</tr>
						<tr>
								<td class="i0">8. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#useipchains">使用ipchains和ipfwadm</a></td>
						</tr>
						<tr>
								<td class="i0">9. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#mix">NAT和包过滤的混合使用</a></td>
						</tr>
						<tr>
								<td class="i0">10. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#difference">iptables和ipchains之间的差别</a></td>
						</tr>
						<tr>
								<td class="i0">11. <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#advice">对制定包过滤器的建议</a></td>
						</tr>
						<tr>
								<td class="name">1.  <a name="intro">简介</a></td>
						</tr>
						<tr>
								<td>欢迎，亲爱的读者。</td>
						</tr>
						<tr>
								<td>这篇文章假设你知道有关IP地址、网络地址、网络掩码、选路和DNS。如果不知道，我建议你先阅读网络概念的HowTo（Network Concepts HOWTO）。</td>
						</tr>
						<tr>
								<td>这篇HOWTO并非一个简要的介绍（会让你发热、发毛，没有安全感），也非一个完全的原始的披露（最吃苦耐劳的人也会被搅晕，不过必定会有所斩获）。</td>
						</tr>
						<tr>
								<td>你的网络并不安全。问题在于，必须获取快速、简洁的通讯，但又必须限于良好的、无恶意的行为，就如同在嘈杂的大戏院里，你可以高谈阔论，但是绝不能大喊：着火了！。这篇HOWTO不能解决这种问题。</td>
						</tr>
						<tr>
								<td class="mine">（译者：所有安全都只是相对的，否则根本不会产生这种东西了）</td>
						</tr>
						<tr>
								<td>因此，你只能决定在哪方面妥协。我想帮助你使用一些可用的工具和一些通常需要注意的漏洞，希望你将它们用在好的一面，而不是出于恶意的目的 -- 另一个同样重要的问题。</td>
						</tr>
						<tr>
								<td>(C) 2000 Paul `Rusty' Russell.  Licenced under the GNU GPL.</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">2、 <a name="officer">官方站点及邮件列表位置</a></td>
						</tr>
						<tr>
								<td>这里有三个官方站点：<br />
  o  Thanks to Filewatcher <a href="http://netfilter.filewatcher.org/">http://netfilter.filewatcher.org</a>.<br />
  o  Thanks to The Samba Team and SGI <a href="http://netfilter.samba.org/">http://netfilter.samba.org</a>.<br />
  o  Thanks to Harald Welte <a href="http://netfilter.gnumonks.org/">http://netfilter.gnumonks.org</a>.<br />
  你可以通过以下站点访问全部相关站点。<br /><a href="http://www.netfilter.org/">http://www.netfilter.org</a> and  <a href="http://www.iptables.org/">http://www.iptables.org</a><br />
  以下是netfilter官方邮件列表<br /><a href="http://www.netfilter.org/contact.html#list">http://www.netfilter.org/contact.html#list</a>.</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">3.<a name="whatis">那么，什么是包过滤器？</a></td>
						</tr>
						<tr>
								<td>包过滤器是这样一种软件：它检查通过的每个包的头部，然后决定如何处置它们。可以这样对待它们：丢弃（也就是说，如果这个包从未被接受，那么丢弃它），通过（也就是说，让包通过），或者更复杂的（操作）。</td>
						</tr>
						<tr>
								<td>Linux下，包过滤内建在内核中（内核模块，或者内建），而且我们还有处理包的一些技巧，不过检查头部和处理包的一般性原则仍在这里。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">3.1 <a name="whyineed">我为何要包过滤？</a></td>
						</tr>
						<tr>
								<td>控制、安全、警戒。</td>
						</tr>
						<tr>
								<td> </td>
						</tr>
						<tr>
								<td class="i0">控制：</td>
						</tr>
						<tr>
								<td>当你用你的Linux服务器把你的内部网和另一个网络（就是Internet吧）连起来，你可以决定哪些通信是允许的，哪些
不允许。例如，包头部包含了包的目标地址，你可以阻碍包发送到（你）确定的几个外部网络，另一个例子，我用NetScape连接到Dilbert
archives。页面上有来自doubleclick.net的广告，然后NetScape浪费了我的时间愉快的下载他们。
告诉包过滤器禁止任何来自或者发往doubleclick.net地址的包，问题就解决了。（当然有更好的办法，见Junkbuster）。</td>
						</tr>
						<tr>
								<td> </td>
						</tr>
						<tr>
								<td class="i0">安全：</td>
						</tr>
						<tr>
								<td>当Linux服务器是混乱的Internet和你良好的、有序的网络之间唯一的东西时，
	你最好能知道哪些东西可以进入你的大门。例如，你可以允许所有（包）从你的网络
	发出，不过你可能会为来自外部的著名的“Ping of Death”而焦急。另一个例子，你不希望
	外人telnet到你的Linux服务器，尽管所有账户都有密码。或许你只想（像绝大多数人）成为
	Internet的旁观者，而非它的服务器（也可能愿意是吧）。简单的不允许任何人接入，设置
	包过滤器拒绝所有进入的包（是不错的办法）。</td>
						</tr>
						<tr>
								<td> </td>
						</tr>
						<tr>
								<td class="i0">警戒：</td>
						</tr>
						<tr>
								<td>有时，本地网络上错误配置的机器可能会向外部喷射出大量的包。最好是当（网络中）出现任何不正常现象时，让包过滤器告诉你。这样你可能可以做点什么，或者你天生就很好奇。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">3.2 <a name="howto">如何在Linux下进行包过滤？</a></td>
						</tr>
						<tr>
								<td>Linux内核在其1.1系列中就有了包过滤功能。第一代，由Alan Cox
1994年移植于BSD的ipfw。这在Linux 2.0中由Jos
Vos和其他人进行了加强；用户空间工具'ipfwadm'可用来控制内核过滤规则。1998年中，我在Michael
Neuling的帮助下，为Linux 2.2进行了重写，推出了用户空间工具'ipchains'。最后，1999年中，基于Linux
2.4的第四代工具，'iptables'，和其他内核的改写正式推出。这就是这个iptables的HOWTO文档的所在。</td>
						</tr>
						<tr>
								<td class="mine">译者：userspace根据台湾同胞的说法，是用来区别系统内存中的适用范围的，分为核心空间和使用者空间，不必深究）</td>
						</tr>
						<tr>
								<td>你需要包含netfilter架构的内核。netfilter是Linux中的一个通用框架，也可以插入（plug in）其他内容（如iptables模块）。也就是说你需要2.3.15及以后版本，而且在配置内核时对CONFIG_NETFILTER回答'Y'。</td>
						</tr>
						<tr>
								<td>iptables这个工具用来和内核交互并告诉它哪些包应该过滤。除非你是程序员或者
  特别好奇，否则这就是你用来控制包过滤的了。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">3.2.1.  <a name="iptables">iptables</a></td>
						</tr>
						<tr>
								<td>iptables工具向内核的包过滤表中插入和删除规则。这就意味着无论怎样设置，启动后信息都会丢失；请参看<a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#permanent">“制定永久性规则”</a>（Making Rules Permanent）来确定如何保证下次启动这些规则能被恢复。</td>
						</tr>
						<tr>
								<td>iptables是ipfwadm和ipchains的替代品。如果你是它们的使用者，请参看
  <a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#useipchains">“使用ipchains和ipfwadm”</a>，如何轻松使用iptables。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">3.2.2 <a name="permanent">创建永久性规则</a></td>
						</tr>
						<tr>
								<td>你当前的防火墙设置保存在内核中，所以重启后就会丢失。你可以试着用iptables-save和iptables-restore脚本来保存他们，并由一个文件恢复。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">4. <a name="whoareyou">你算老几，凭什么玩弄我的内核？</a></td>
						</tr>
						<tr>
								<td>我是Rusty Russell。Linux IP防火墙的维护者，也是一个适当的时候出现在适当的地方的coder。我写了ipchains（参见<a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#howto">“如何在Linux下进行包过滤？”</a>看看实际的工作其实由哪些人完成），并希望能学到足够的东西修正这次的包过滤。</td>
						</tr>
						<tr>
								<td>
										<a href="http://www.watchguard.com/" target="_blank">WatchGuard</a>，一个非常出色的防火墙公司，总之一堆广告，此处省略一千字……</td>
						</tr>
						<tr>
								<td>在此，我想澄清一个误解：我不是内核专家，我了解它，是因为我的核心工作让我接触了他们：David S.
Miller, Alexey Kuznetsov, Andi Kleen, Alan
Cox。无论如何，他们做了最深层的工作，轮到我时，已经非常安全和容易了。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">5. <a name="fast">Rusty的真正的包过滤快速指南</a></td>
						</tr>
						<tr>
								<td>绝大部分人只有一个PPP连接到Internet，而且不希望有人由此进入他们的网络或者防火墙：</td>
						</tr>
						<tr>
								<td> #  插入connection-tracking模块（如国内建在内核中就不需要）</td>
						</tr>
						<tr>
								<td># insmod ip_conntrack</td>
						</tr>
						<tr>
								<td># insmod ip_conntrack_ftp</td>
						</tr>
						<tr>
								<td> </td>
						</tr>
						<tr>
								<td>#  对创建大量新的连接创建一个链，除非这些连接来自内部。</td>
						</tr>
						<tr>
								<td># iptables -N block</td>
						</tr>
						<tr>
								<td># iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT</td>
						</tr>
						<tr>
								<td># iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT</td>
						</tr>
						<tr>
								<td># iptables -A block -j DROP</td>
						</tr>
						<tr>
								<td> </td>
						</tr>
						<tr>
								<td>#  由INPUT和FORWARD链跳往（刚刚创建的）那条链。</td>
						</tr>
						<tr>
								<td># iptables -A INPUT -j block</td>
						</tr>
						<tr>
								<td># iptables -A FORWARD -j block</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name"> 6.  <a name="howpass">包是如何穿过过滤器的</a></td>
						</tr>
						<tr>
								<td>内核由'filter'表中的以下三个规则开始。这些被称为防火墙链或就叫链。这三个链分别是 INPUT、OUTPUT和FORWARD。</td>
						</tr>
						<tr>
								<td> 对于ASCII艺术迷来说，链好象这样：（注意：这与2.0和2.2内核非常不同）</td>
						</tr>
						<tr>
								<td class="mine">译者：ASCII艺术，这里指的是利用纯ASCII文本作图</td>
						</tr>
						<tr>
								<td>
										<pre>                         _____<br />  Incoming                 /     \         Outgoing<br />         --&gt;[Routing ]---&gt;|FORWARD|-------&gt;<br />            [Decision]     \_____/        ^<br />                 |                        |<br />                 v                       ____<br />                ___                     /    \<br />               /   \                 |OUTPUT|<br />              |INPUT|                  \____/<br />               \___/                      ^<br />                 |                        |<br />                  ----&gt; Local Process ----</pre>
								</td>
						</tr>
						<tr>
								<td>三个圈代表上面说的三个链。当包到达图中的一个圈，那个链就检查并确定包的命运。
  如果链决定DROP包，包在那里就被杀死。但是如果链决定让包ACCEPT，包就继续在图中前进。</td>
						</tr>
						<tr>
								<td>一个链是规则的列表。每个规则都会说：'如果包头看上去像这个的话，那么就这样处理'。
  如果规则和包不匹配，由链中的下一个规则处理。最后，如果再也没有要进行处理的规则了，
  内核就根据链的原则（policy，有时称为默认规则）来决定应当如何做。在一个注重安全的
  系统中，原则通常是让内核丢弃这个包。</td>
						</tr>
						<tr>
								<td>1. 当一个包进入时（就是由以太网卡），内核首先检查包的目的地。这被称作“选路”。</td>
						</tr>
						<tr>
								<td>2. 如果它就是进入本机的，包会向图中的下方移动，到达INPUT链。如果到了这里，任何等待这个包的进程都会收到它。</td>
						</tr>
						<tr>
								<td> 3. 否则，如果内核未被允许转发，或者不知道该如何转发这个包，它会被丢弃。如果允许转发，而且包的目的地是另一个网络接口（如果你有另一个的话），那么包向我们图中的右边行进，到达FORWARD链。如果允许通过（ACCEPT），它就被送了出去。</td>
						</tr>
						<tr>
								<td>4. 最后，服务器上运行的程序可以发送网络包。这些包马上通过OUTPUT链。如果被允（ACCEPT），那么包继续向可以到达它的目的地的网络接口发送。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7. <a name="useiptables">使用iptables</a></td>
						</tr>
						<tr>
								<td>iptables有着非常详尽的使用手册(man iptables)，而且如果你需要某个选项更详细的介绍。看看<a href="http://cmpp.linuxforum.net/NetSnake/pfhtcn.html#difference">“iptables和ipchains的差别”</a>可能对你非常有用。</td>
						</tr>
						<tr>
								<td>使用iptables你可以做很多不同的事。开始的内建的三个链INPUT、OUTPUT和FORWARD是不能被删除的。让我们看看整个链的管理。</td>
						</tr>
						<tr>
								<td>1. 创建一个新的链 (-N)。</td>
						</tr>
						<tr>
								<td>2. 删除一个空链(-X)。</td>
						</tr>
						<tr>
								<td>3.修改内建链的原则(-P)。</td>
						</tr>
						<tr>
								<td>4. 显示链中的规则（表）(-L)。</td>
						</tr>
						<tr>
								<td>5. 清空一个链(-F)。</td>
						</tr>
						<tr>
								<td>6. 将链中所有规则的包和字节计数器清零(-Z)。</td>
						</tr>
						<tr>
								<td>有几种办法操作链中的规则：</td>
						</tr>
						<tr>
								<td>1. 向链中添加一条新规则(-A)。</td>
						</tr>
						<tr>
								<td>2. 在链中某个位置插入一条新规则(-I)。</td>
						</tr>
						<tr>
								<td>3. 替换某个位置的规则(-R)。</td>
						</tr>
						<tr>
								<td>4. 删除链中某个位置的规则，或者是第一个被匹配的。(-D)。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7.1.  <a name="afterboot">当计算机启动后你会看到的</a></td>
						</tr>
						<tr>
								<td>ptables可以作为模块，称为'iptables_filter.o，可以在第一次运行iptables时自动被装载。也可以永久性的编到内核中。</td>
						</tr>
						<tr>
								<td>在所有iptables命令执行之前（当心：某些发布版会在初始化脚本中运行iptables），所有内建链中都没有任何规
则（'INPUT'、'FORWARD'和'OUTPUT')，所有链的原则都是ACCEPT。你可以在装载iptable_filter模块时，提供
'forward=0'选项来修改FORWARD的默认原则。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7.2.  <a name="justrule">对单个规则的操作</a></td>
						</tr>
						<tr>
								<td>这是基本的包过滤：管理规则，添加(-A)和删除(-D)命令可能是最常用的。其他的(-I插入和-R替换）只是简单的扩展而已。</td>
						</tr>
						<tr>
								<td>
每个规则都有一组条件来匹配包，和如果匹配了该如何做（target）。例如，你可能希望丢弃所有来自127.0.0.1的ICMP包。这样我们的条件就
是协议必须是ICMP，而且源地址必须是127.0.0.1，我们的目标是丢弃(DROP)。127.0.0.1是一个回送接口，即使你没有真正的网络连
接它也会存在。你可以用ping程序生成这样的包（它简单的发送ICMP 类型8（echo request），所有愿意响应的主机都会用ICMP
类型0（echo reply）来响应）。这对于测试非常有用。</td>
						</tr>
						<tr>
								<td># ping -c 1 127.0.0.1</td>
						</tr>
						<tr>
								<td>PING 127.0.0.1 (127.0.0.1): 56 data bytes</td>
						</tr>
						<tr>
								<td>64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms</td>
						</tr>
						<tr>
								<td>--- 127.0.0.1 ping statistics ---</td>
						</tr>
						<tr>
								<td>1 packets transmitted, 1 packets received, 0% packet loss</td>
						</tr>
						<tr>
								<td>round-trip min/avg/max = 0.2/0.2/0.2 ms</td>
						</tr>
						<tr>
								<td># iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP</td>
						</tr>
						<tr>
								<td># ping -c 1 127.0.0.1</td>
						</tr>
						<tr>
								<td>PING 127.0.0.1 (127.0.0.1): 56 data bytes</td>
						</tr>
						<tr>
								<td>--- 127.0.0.1 ping statistics ---</td>
						</tr>
						<tr>
								<td>1 packets transmitted, 0 packets received, 100% packet loss</td>
						</tr>
						<tr>
								<td>这里，第一个ping是成功的（'-c 1'告诉ping只发送一个包）</td>
						</tr>
						<tr>
								<td>然后我们可以向'INPUT'链中添加（-A）一个规则，制定来自127.0.0.1('-s 127.0.0.1')的ICMP协议('-p icmp')包都将被丢弃('-j DROP')。</td>
						</tr>
						<tr>
								<td>然后我们测试我们的规则，用第二个ping。在程序放弃等待永远不可能的响应之前，会暂停一下。</td>
						</tr>
						<tr>
								<td>我们可以用两种办法中的任一种删除规则。首先，因为知道这是INPUT链中唯一的规则，我们用编号删除：</td>
						</tr>
						<tr>
								<td># iptables -D INPUT 1</td>
						</tr>
						<tr>
								<td>删除INPUT链中的编号为1的规则</td>
						</tr>
						<tr>
								<td>第二种办法是 -A 命令的映射，不过用-D替换-A。当你的链中规则很复杂，而你不想计算它们的编号的时候这就十分有用了。这样的话，我们可以使用：</td>
						</tr>
						<tr>
								<td># iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP</td>
						</tr>
						<tr>
								<td>-D的语法必须和-A（或者-I或者-R）一样精确。如果链中有多个相同的规则，只会删除第一个。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7.3 <a name="filters">过滤规格</a></td>
						</tr>
						<tr>
								<td>我们已经看了，用'-p'指定协议，用'-s'指定源地址，不过还有其他选项我们可以用来指定包的特征。下面是一个详细的手册。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7.3.1 <a name="sdip">指定源和目的IP地址</a></td>
						</tr>
						<tr>
								<td>源（'-s'，'--source'或'--src'）和目的（'-d'，'--destination'或'--
dst'）IP地址可以用四种办法指定。最常用的方法是使用全名，就像'localhost'或者'www.linuxhq.com'。第二种办法是指定
IP地址，如'127.0.0.1'。</td>
						</tr>
						<tr>
								<td>第三和第四种办法允许指定一组IP地址，就像'199.95.207.0/24'或者
'199.95.207.0/255.255.255.0'。这指定了从199.95.207.0到199.95.207.255范围内的所有IP地址。
'/'后面的数字说明哪部分IP地址是有效的。'32'或者'255.255.255.255‘为默认的（匹配整个IP地址）。用'/0'来指定任何IP
地址，像这样：</td>
						</tr>
						<tr>
								<td># '-s 0/0'在这里是多余的</td>
						</tr>
						<tr>
								<td># iptables -A INPUT -s 0/0 -j DROP</td>
						</tr>
						<tr>
								<td>这很少用到，这和上面出现过的不指定'-s'结果完全一样。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name"> 7.3.2 <a name="inversions">反向指定</a></td>
						</tr>
						<tr>
								<td> 很多标记，包括'-s'（或'--source'）和'-d'（'--destination'）标记可以在前面加上'!'标志（读作'not'），来匹配所有和给出的 NOT 的地址。例如， '-s ! localhost'匹配所有不是来自本机的包。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7.3.3 <a name="protocols">协议指定</a></td>
						</tr>
						<tr>
								<td>可以用'-p'（或'--protocol'）指定协议。协议可以是数字（如果你知道IP的协议数值）或者像'TCP'、'UDP'或者'ICMP'这类的名称。大小写无所谓，所以'tcp'和'TCP'一样。</td>
						</tr>
						<tr>
								<td>协议名称前可加上'!'，以反向解释它，例如'-p ! TCP'将匹配所有不是TCP的包。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name">7.3.4 <a name="interfaces">接口指定</a></td>
						</tr>
						<tr>
								<td>'-i'（或'--in-interface'）和'-o'（或'--out-interface'）选项指定匹配的接口名。接口可以是包进入的('-i')或者送出('-o')的物理设备。你可以用ifconfig命令列出当前'up'的接口。（也就是说正在工作的）。</td>
						</tr>
						<tr>
								<td>通过INPUT链的包不会有送出接口，所以在这个链中'-o'永远不会匹配。同样，通过OUTPUT链的包也没有进入接口，这个链中的'-i'也不会被匹配。</td>
						</tr>
						<tr>
								<td>只有通过FORWARD链的包才有进入和送出两个接口。</td>
						</tr>
						<tr>
								<td>可以指定一个当前不存在的接口。在这个接口可用之前，规则不能匹配任何东西。这对于拨号PPP连接及类似的非常有用（通常是ppp0接口）。</td>
						</tr>
						<tr>
								<td>一个特殊情况，接口名后面是一个'+'，那就会匹配以这个字符串开头的所有接口（无论当前是否存在）。例如，指定一个匹配所有ppp接口的规则，要用到-i ppp+选项。</td>
						</tr>
						<tr>
								<td>接口名也可以在前面插入 '!'，来匹配所有与指定接口不同的包，如-i ! ppp+。</td>
						</tr>
						<tr>
								<td class="i0">
										<hr />
								</td>
						</tr>
						<tr>
								<td class="name"> 7.3.5 <a name="frags">分片指定</a></td>
						</tr>
						<tr>
								<td class="mine">
	译者：为帮助大家理解，此处附上IP数据报的格式，摘自《Internetworking with TCP/IP》<br /><table align="center" width="50%"><tbody><tr><td class="i0" style="color: rgb(51, 153, 51);">0</td><td class="i0" style="color: rgb(51, 153, 51);">4</td><td class="i0" style="color: rgb(51, 153, 51);">8</td><td colspan="" class="i0" style="color: rgb(51, 153, 51);">16</td><td class="i0" style="color: rgb(51, 153, 51);">19</td><td class="i0" style="color: rgb(51, 153, 51);">24</td><td class="i0" rowspan="9" style="color: rgb(51, 153, 51);" valign="top">31</td></tr><tr><td class="draw">版本号</td><td class="draw">首部长度</td><td class="draw">服务类型</td><td colspan="3" class="draw">总长度</td></tr><tr><td colspan="3" class="draw">标志符</td><td class="draw">标志</td><td colspan="2" class="draw">分片偏移量</td></tr><tr><td colspan="2" class="draw">寿命</td><td class="draw">协议</td><td colspan="3" class="draw">首部效验和</td></tr><tr><td class="draw" colspan="6">源IP地址</td></tr><tr><td class="draw" colspan="6">目的IP地址</td></tr><tr><td class="draw" colspan="5">IP选项</td><td class="draw">填充</td></tr><tr><td class="draw" colspan="6">数据</td></tr><tr><td class="draw" colspan="6">……</td></tr></tbody></table><br /><table><tbody><tr><td>有时一个包太大，不可能适合所有线路。这样的话，包会被分成片，然后当作多个包发送。最终重组这些分片来重建整个包。</td></tr><tr><td>分片的问题是，被检查的初始片含有整个头部字段（IP+TCP，UDP和ICMP），但随后的包只有一部分头（没有附加协议字段的IP），因此，检查后面的分片的头部（就像有TCP、UDP和ICMP一样）是不可能的。</td></tr><tr><td>如果你在做NAT或连接追踪，那么所有分片在包过滤代码处理以前都会合并，所以你不需要为分片担心。</td></tr><tr><td>还请注意，到filter表中的INPUT链（或者任何由NF_IP_LOCAL_IN钩子程序钩入的表）的包实际上由核心IP栈片重组后到达。</td></tr><tr><td>否则，理解分片是如何被过滤规则处理的就非常重要了。任何过滤规则要求我们没有的信息，将被认为不匹配。这意味着（分片的）
第一片像普通的包一样被处理。第二及后面的片则不会。因此，规则 -p TCP --sport
www（指定源端口为'www'）永远不会匹配一个分片（的包）（除了第一片），相反的规则 -p TCP --sport ! www也不会。</td></tr><tr><td>无论如何，你可以用'-f'（或'--fragment'）标记指定专门处理第二及以后的分片的规则。当然也可以指定一个规则，让它不去匹配第二及以后的分片，在'-f'前加上'!'。</td></tr><tr><td>通常，让第二及以后的分片通过被认为是安全的，因为如果过滤处理了第一片，那么就无法在目标主机上进行重组。不过，已知的Bug是发送分片可能会轻易的让主机崩溃。你自己看着办吧。</td></tr><tr><td>网络高手注意：当这类检查进行时，畸形的包（防火墙读取的ICMP代码和类型过短的TCP、UDP和ICMP包）都将被丢弃。所以TCP分片从位置8开始。（译者：什么意思？大概是指IP包中的首部字段位置）</td></tr><tr><td>例如，下面的规则会丢弃任何发往192.168.1.1的分片。</td></tr><tr><td> # iptables -A OUTPUT -f -d 192.168.1.1 -j DROP</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.3.6 <a name="newmatch">iptables扩展：新的匹配</a></td></tr><tr><td>iptables是可扩展的，也就是包括内核和iptables工具都可以扩充新的特性。</td></tr><tr><td>下列部分扩展是标准的，其他的则是派生的。其他人可以做出扩展并发布给合适的人。</td></tr><tr><td>内核扩展一般位于内核模块子目录，诸如/lib/modules/2.4.0-test10/kernel/net/ipv4/netfilter。如果你使用了CONFIG_KMOD设置来编译内核，那么它们要求被装载，所以你不需要手工插入。</td></tr><tr><td>iptables程序扩展通常是位于/usr/local/lib/iptables/下的共享库，当然也可能在/lib/iptables或者/usr/lib/iptables，具体的要根据不同的发行版本来确定。</td></tr><tr><td>扩展有两种：新的目标，新的匹配（我们马上会谈到新的目标）。有些协议自动给出新的测试：如下所示，现有的包括TCP、UDP和ICMP。</td></tr><tr><td>这样，你可以在命令行中在 '-p'选项后指定新的测试，就可以载入扩展（模块）了。当允许扩展时，可以用'-m'选项装入扩展。</td></tr><tr><td>在选项后面（'-p'，'-j'或者'-m'）加上 '-h'或'--help'来获取扩展的帮助。</td></tr><tr><td> # iptables -p tcp --help</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.3.6.1.  <a name="etcp">TCP 扩展</a></td></tr><tr><td>如果指定了'-p tcp'，那么TCP扩展将自动加载，并提供下列选项（不匹配分片）。</td></tr><tr><td>--tcp-flags</td></tr><tr><td class="i2">可附加一个'!'。有两个标志字串可以通过TCP标记来过滤。第一个标志字符串是mask：你想要测验的标志列表。第二个指出哪些将要被设置。例如：</td></tr><tr><td class="i2"># iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP</td></tr><tr><td class="i2">意思是所有标志都将被测试（'ALL'和'SYN, ACK,FIN,RST,URG,PSH'同义），不过只设置SYN和ACK。当然也可以用'NONE'表示无标志。</td></tr><tr><td class="i2">--syn</td></tr><tr><td class="i2">前面的'!'是可选的，是'--tcp-flags SYN, RST, ACK, SYN'的缩写</td></tr><tr><td>--source-port</td></tr><tr><td class="i2">后面可以跟一个'!'，可以是单个TCP端口，或一段端口。可以是/etc/services中的端口名或者数字。端口范围格式是低端口名 : 高端口名，或者（指定大于或等于给出的端口）是端口名 + ：，或者（指定小于或等于给出的端口）是: + 端口名。</td></tr><tr><td>--sport</td></tr><tr><td class="i2">就是 '--source-port'。</td></tr><tr><td>--destination-port</td></tr><tr><td>--dport</td></tr><tr><td class="i2">和上面类似，不过是指定匹配的目的端口（范围）。</td></tr><tr><td>--tcp-option</td></tr><tr><td class="i2">可以跟一个'!'和一个数字，匹配的是TCP选项和数字相等的包。如果试图用
	这个TCP选项匹配一个没有完整的TCP包头的包，那么这个包会被自动丢弃。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.3.6.1.1.  <a name="tcpflag">TCP标志的解释</a></td></tr><tr><td>有时只允许单向的TCP连接会很有用。例如，你可能会允许连接到外部WWW服务器，但不会允许来自那个服务器的连接。</td></tr><tr><td>最简单的举动可能是阻止来自那个服务器的包，可惜，TCP连接需要包双向传送（才能正常工作）。</td></tr><tr><td>解决办法是，只阻挡那些用来请求连接的包。这些包称为SYN包（OK，从技术上说，它们的SYN标志被设置，而没有设置RST和ACK标志，不过我们简单的称为SYN包）。通过只阻止这种包，我们就可以阻止来自那些地方的连接企图。</td></tr><tr><td>'--syn'标志是这样用的：只对指定了TCP协议的规则有效。例如，指定来自192.168.1.1的连接请求。</td></tr><tr><td> -p TCP -s 192.168.1.1 --syn</td></tr><tr><td>当然也可以在前面加上'!'，意即所有不是初始连接的包。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.3.6.2 <a name="eudp">UDP 扩展</a></td></tr><tr><td>这些扩展在指定'-p udp'时自动加载。可以提供 '--source-port'、'--sport'、'--destination-port'和'--dport'等和TCP类似的选项。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.3.6.3 <a name="eicmp">ICMP扩展</a></td></tr><tr><td>这些扩展在指定'-p icmp'时自动加载。只提供一个新的选项：</td></tr><tr><td>--icmp-type</td></tr><tr><td class="i2">可以跟'!'，icmp类型名称（如'host-unreachable'）或者数值（如'3'），或者数值类型/代码（如'3/3'）。用'-p icmp --help'可以列出可用的icmp类型名。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.3.6.4 <a name="eother">其他匹配的扩展</a></td></tr><tr><td>这些netfilter包中的其他扩展尚属于演示阶段，（如果安装了的话）可以用'-m'来启用。</td></tr><tr><td>mac</td></tr><tr><td> --mac-source</td></tr><tr><td>可以跟一个'!'，后面是以太网地址，用冒号分隔的16近制表示，如`--mac-source 00:60:08:91:CC:B7'。</td></tr><tr><td>limit</td></tr><tr><td>此模块必须明确指定'-m limit'或'--match limit'。用来限制匹配的速率。就像抑制记录信息。只会匹配给定的数字/每秒（默认是每小时3个匹配，和5个触发）。可以有两个参数：</td></tr><tr><td>--limit</td></tr><tr><td>后面跟数字：指定每秒钟允许的匹配最大平均数。这个数字可以指定
	   明确的单位，使用'/second'、`/minute'、`/hour' 或者 `/day'，或者
	   只写一部分（如'5/second'和'5/s'一样）。</td></tr><tr><td>--limit-burst</td></tr><tr><td>后面跟一个数字，指明在上面的limit起作用前最大的触发值。</td></tr><tr><td>这个匹配（项）通常和LOG目标结合起来使用，以对速率限制进行记录。
	为了理解它是如何工作的，我们来看看下面这条规则，它使用默认限制参数
	记录包。</td></tr><tr><td># iptables -A FORWARD -m limit -j LOG</td></tr><tr><td>当这条规则第一次启用时，包开始被记录。实际上，由于默认触发是5，前五个包会被记录。然后，每隔20分钟再记录一次包，无
论这期间有多少包到达。而且，每个不匹配包的20分钟间隔里，会恢复一个触发（值）。如果100分钟都没有包到达这个规则，那么所有触发都会恢复，回到起
点。</td></tr><tr><td>提示：你目前不能以大于59小时的时间来创建这种规则，所以如果你设置一个平均率为一天，那么你的触发率必须小于3。</td></tr><tr><td>你也可以将此模块用于避免使用快速响应速率的各类拒绝服务攻击(DoS，Denial of Server）。</td></tr><tr><td class="mine">（译者：以下是较著名的攻击）</td></tr><tr><td>Syn-flood protection:</td></tr><tr><td># iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT</td></tr><tr><td> </td></tr><tr><td>Furtive port scanner:</td></tr><tr><td># iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT</td></tr><tr><td> </td></tr><tr><td>Ping of death:</td></tr><tr><td># iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT</td></tr><tr><td> 这个模块工作原理类似于“节流阀”，以下是图示。</td></tr><tr><td><pre><br /><br />                 rate (pkt/s)<br />                       ^        .---.<br />                       |       / DoS \<br />                       |      /       \<br />          Edge of DoS -|.....:.........\....................... DoS的边界 = <br />           = (limit *  |    /:          \<br />          limit-burst) |   / :           \         .-.<br />                       |  /  :            \       /   \<br />                       | /   :             \     /     \<br />          End of DoS  -|/....:..............:.../.......\..../.  DoS结束<br />           = limit     |     :              :`-'         `--'<br />          -------------+-----+--------------+------------------&gt; time (s)<br />             LOGIC =&gt;  Match | Didn't Match |    Match<br /><br /></pre></td></tr><tr><td>我们匹配由五个包触发的每秒一个包，不过每秒钟第四个包才开始进入（这个规则），进行三秒钟，然后重新开始。</td></tr><tr><td><pre>                  &lt;--Flood 1--&gt;           &lt;---Flood 2---&gt;<br /><br />          Total  ^                   Line  __--      YNNN<br />          Packets|               Rate  __--      YNNN<br />                 |            mum  __--      YNNN<br />              10 |        Maxi __--         Y<br />                 |         __--            Y<br />                 |     __--               Y<br />                 | __--    YNNN<br />                 |-    YNNN<br />               5 |    Y<br />                 |   Y                                Key:  Y -&gt; Matched Rule<br />                 |  Y                                       N -&gt; Didn't Match Rule<br />                 | Y<br />                 |Y<br />               0 +--------------------------------------------------&gt;  Time (seconds)<br />                  0   1   2   3   4   5   6   7   8   9  10  11  12<br /><br /></pre></td></tr><tr><td>你可以看见，前五个包是允许超过一个包/每秒（这个速率）的，然后就开始限制。
     如果有一个暂停，那么另一个触发也是允许的，但不能超过规则设置的最大速率。</td></tr><tr><td>owner</td></tr><tr><td> --uid-owner userid</td></tr><tr><td>根据给出的有效的（数值）user id来匹配包的创建进程。</td></tr><tr><td>--gid-owner groupid</td></tr><tr><td>根据给出的有效的（数值）group id 来匹配包的创建进程。</td></tr><tr><td>--pid-owner processid</td></tr><tr><td>根据给出的process id 来匹配包的创建进程。</td></tr><tr><td> --sid-owner sessionid</td></tr><tr><td>根据给出的 session group 来匹配包的创建进程。</td></tr><tr><td>unclean</td></tr><tr><td>这是试验性模块，必须明确指定'-m unclean'或者'--match unclean'。
	它对包进行各种随机判断。此模块还未通过审核，所以不要用在安全设施上。
	（可能造成更糟糕的结果，它自己可能还有Bug）。没有提供选项。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name"> 7.3.6.5 <a name="status">状态匹配</a></td></tr><tr><td>最有用的匹配标准是'state'扩展。它负责解释'ip_conntrack'模块的connection-tracking分析。
  这是推荐使用的（好东东）。</td></tr><tr><td>通过指定'-m state'来允许附加的'--state'选项，匹配用逗号分割的状态列表（'!'标志表明不符合那些状态（的状态））。</td></tr><tr><td>NEW</td></tr><tr><td>由新连接创建的包</td></tr><tr><td>ESTABLISHED</td></tr><tr><td>属于已存在连接的包（也就是说，响应的包）</td></tr><tr><td>RELATED</td></tr><tr><td>和一个已存在连接有关，但不是它的一部分的包。如ICMP错误，或者（已加载FTP模块）一个建立FTP数据连接的包。</td></tr><tr><td>INVALID</td></tr><tr><td>由于以下原因而不能被识别的包：包括内存不足和不是相应当前任何连接的ICMP错误。通常这些包会被丢弃。</td></tr><tr><td>这个强大的匹配扩展的一个例子：</td></tr><tr><td># iptables -A FORWARD -i ppp0 -m state ! --state NEW -j DROP</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name"> 7.4 <a name="dests">目标规格</a></td></tr><tr><td>现在，我们知道了如何对包进行测试，但是我们还需要告诉那些匹配的包应该如何做。这被称作规则的目标。</td></tr><tr><td>有两个很简单的内建目标：DROP和ACCEPT。我们已经看过了。如果包匹配的规则，其目标是这二者中的一个，那么不再考虑更多的规则了：包的命运已经决定。</td></tr><tr><td>除此之外有两种目标：扩展的和用户定义的链。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.4.1 <a name="udc">用户定义链</a></td></tr><tr><td>iptables一个强大的特点是由ipchains继承来的可以让用户创建新的链，附加在三个内建的链上（INPUT、
FORWARD和OUTPUT）。按照惯例，用户定义链使用小写以区分他们。（我们会在“Operations on an Entire
Chains”中描述如何创建新的用户定义链）。</td></tr><tr><td>当包匹配的链的目标是一个用户定义链时，包就转移到用户定义链中的规则。如果
  没有决定包的命运，那么包在（用户定义链）中的移动就结束了，并回到当前链的下一个规则。</td></tr><tr><td>搞搞ASCII艺术吧。考虑两个（笨蛋）链：INPUT（内建的）和test（用户定义的）。</td></tr><tr><td><pre>                `INPUT'                         `test'<br />               ----------------------------    ----------------------------<br />               | Rule1: -p ICMP -j DROP   |    | Rule1: -s 192.168.1.1    |<br />               |--------------------------|    |--------------------------|<br />               | Rule2: -p TCP -j test    |    | Rule2: -d 192.168.1.1    |<br />               |--------------------------|    ----------------------------<br />               | Rule3: -p UDP -j DROP    |<br />               ----------------------------</pre></td></tr><tr><td>考虑一个由192.168.1.1到1.2.3.4的TCP包。它进入INPUT链，由Rule1检查 - 不匹配。
  Rule2匹配，那么它的目标就是test，所以下一个检查由test开始。test中的第一个规则
  Rule1是匹配的，但是没有指定目标，所以由第二个规则Rule2检查。结果是不匹配，而我们
  到达了链的尾部。于是回到INPUT链，因为刚刚被Rule2检查，所以现在由Rule3来检查，仍然
  不匹配。</td></tr><tr><td>所以这个包的路线是：</td></tr><tr><td><pre>                                       v    __________________________<br />                `INPUT'                |   /    `test'                v<br />               ------------------------|--/    -----------------------|----<br />               | Rule1                 | /|    | Rule1                |   |<br />               |-----------------------|/-|    |----------------------|---|<br />               | Rule2                 /  |    | Rule2                |   |<br />               |--------------------------|    -----------------------v----<br />               | Rule3                 /--+___________________________/<br />               ------------------------|---<br />                                       v<br /></pre></td></tr><tr><td>用户定义链可以跳转到另一个用户定义链（不过不能循环：如果发现循环，包就会被丢弃）。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.4.2 <a name="newtarget">iptables扩展：新目标</a></td></tr><tr><td>其他类型的扩展是目标。目标扩展由内核模块组成，而且iptables的一个可选扩展提供了新的命令行选项。有几个扩展是包含在默认netfilter发布中的。</td></tr><tr><td>LOG</td></tr><tr><td>--log-level</td></tr><tr><td>跟一个级别名称或数字。合适的名字是（忽略大小写）'debug'、'info'、'notice'、'warning'、
'err'、'crit'、'alert'和'emerg'，相当于数字7到0。请参考syslog.conf的手册获取这些级别的说明。默认是
'warning'。</td></tr><tr><td>--log-prefix</td></tr><tr><td>跟一个最多29个字符的字符串，它被写入到log信息的开始处，这样可以区别出来。</td></tr><tr><td>这个模块最有用的就是跟在limit match后面，这样你就不会被你的log淹没了。</td></tr><tr><td>REJECT</td></tr><tr><td>此模块和'DROP'效果一样，除了会发送一个'port unreachable'的ICMP错误报文。注意如果属于以下情况，ICMP错误报文不会发送：</td></tr><tr><td>o  包一开始就是ICMP错误报文，或者是未知的ICMP类型。</td></tr><tr><td>o 包被作为无头的分片过滤了。</td></tr><tr><td>o  我们已经向那里发送了太多的ICMP错误报文（参见/proc/sys/net/ipv4/icmp ratelimit）。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.4.3 <a name="sbuiltin">特殊的内建目标</a></td></tr><tr><td>有两个特殊的内建目标：RETURN和QUEUE。</td></tr><tr><td>RETURN如同到达这个链的尾部：如果是内建的链的规则，那么这个链的默认规则将被执行。如果是用户定义链，当跳至这个链中的这条规则（包含RETURN）时，回到前面的链继续匹配。</td></tr><tr><td>QUEUE是一个特别的目标，会为用户空间进程队列这个包。要这样使用，需要两个部件：</td></tr><tr><td>o 一个"queue handler"，处理用户空间与内核之间的机制。</td></tr><tr><td>o 和一个用户空间用来接收的应用程序，可能是操作，以及对包进行裁决。</td></tr><tr><td>IPv4 iptables的标准queue handler是 ip_queue 模块，跟随内核发布并标记为实验中。</td></tr><tr><td>下面是一个如何用iptables为用户空间进程队列包的快速例子：</td></tr><tr><td># modprobe iptable_filter</td></tr><tr><td># modprobe ip_queue</td></tr><tr><td># iptables -A OUTPUT -p icmp -j QUEUE</td></tr><tr><td>在这个例子中，本地生成的送出ICMP包（如由ping产生）到达ip_queue模块，然后包被试图送往用户空间应用。如果没有用户空间应用在（那儿）等着，包就被丢弃了。</td></tr><tr><td>要写一个用户空间应用，需要libipq API。和iptables一起发布。在CVS的testsuite
  tools（如redirect.c）中可以找到相关例子。</td></tr><tr><td>可以通过这里检查ip_queue的状态：</td></tr><tr><td> /proc/net/ip_queue</td></tr><tr><td>队列的最大长度（也就是不包含返回包的送往用户空间包的数量）可以通过这里控制：</td></tr><tr><td>/proc/sys/net/ipv4/ip_queue_maxlen</td></tr><tr><td>默认队列长度是1024。一旦达到这个长度，新的包就会被丢弃，直到队列长度小于这个值。好的协议如TCP，会对丢弃的包作出拥挤的解释，而且在队列满了后会很理想的将它挡回。无论如何，如果默认值太小的话，最好是多实验以决定队列的最大长度。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.5  <a name="wholechain">对整个链进行操作</a></td></tr><tr><td>iptables一个非常有用的特性是可以将链中相关的规则成组。你可以随意给链取名，不过我建议使用小写字母以避免与内建的链和目标产生冲突。链的名称最长为31个字母。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.5.1 <a name="createchain">创建新链</a></td></tr><tr><td>让我们创建一个新链。因为我是个充满想象的家伙，我叫它test。使用'-N'或'--new-chain'选项：</td></tr><tr><td># iptables -N test</td></tr><tr><td>如此简单，现在你可以像上面说的那样放入规则了。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.5.2 <a name="deletechain">删除链</a></td></tr><tr><td>删除一个链同样简单，使用 '-X'或'--delete-chain'选项。为什么是'-X'？嗯，因为所有合适的字母都已经被使用了。</td></tr><tr><td># iptables -X test</td></tr><tr><td>有几个删除链的限制：他们必须是空的（见下面的"Flushing a Chain"）而且他们不能是任何规则的目标。你也不能删除任何一个内建的链。</td></tr><tr><td> 如果你不指定链名的话，所有可以被删除的用户定义链都将被删除。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.5.3 <a name="flushchain">清空一个链</a></td></tr><tr><td>这是清除一个链中所有规则的简单方法，使用'-F' 或 '--flush'命令。</td></tr><tr><td># iptables -F FORWARD</td></tr><tr><td>如果不指定链的话，所有链都将被清空。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name"> 7.5.4 <a name="listchain">对链进行列表</a></td></tr><tr><td>用'-L'或'--list'命令，你可以列出一个链中的所有规则。</td></tr><tr><td>用户定义链中的'refcnt'是有多少链的规则指向了它。这个值必须为0，然后才可以删除这个链。</td></tr><tr><td>如果链名被忽略，所有链都将被列出，即便是空的。</td></tr><tr><td>'-L'可以有三个选项。'-n'(数字）选项对于阻止iptables试图查找IP地址时非常有用，因为（如果你像大多数人一样使用DNS）如果你的DNS设置不太合适的话，可能会造成长时间的停顿，或者你滤掉了DNS请求。它还会让TCP或UDP端口以数字显示。</td></tr><tr><td>'-v'选项显示所有规则的细节，包括饱和字节计数器，TOS比较，以及接口。否则这些值是被忽略的。</td></tr><tr><td>注意，报和字节计数器可以分别使用'K'、'M'或者'G'来代替1000、1,000,000 和1,000,000,000。使用'-x'（扩展数字）标志来打印整个值，不管它有多大。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">7.5.5 <a name="zerocounter">重置（清零）计数器</a></td></tr><tr><td>可以重置计数器非常有用。可以用'-Z'或'--zero'来完成。</td></tr><tr><td>考虑下面的：</td></tr><tr><td># iptables -L FORWARD</td></tr><tr><td># iptables -Z FORWARD</td></tr><tr><td>在上述例子中，有些包在'-L'和'-Z'命令之间通过。因此，你可以把'-L'和'-Z'一起使用，读取时就清空计数器。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name"> 7.5.6  <a name="setpolicy">设置原则（默认规则）</a></td></tr><tr><td>我们在前面讨论包是如何通过链的时候，已经解释了当包到达内建链的尾部时会发生什么。这时，链的原则就决定包的命运。只有内建的链（INPUT、OUTPUT和FORWARD）有原则，因为如果包到达用户定义链的尾部会返回到前面的链。
</td></tr><tr><td>原则可以是ACCEPT或DROP，例如：</td></tr><tr><td># iptables -P FORWARD DROP</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">8. <a name="useipchains">使用ipchains和ipfwadm</a></td></tr><tr><td>netflter发布中有ipchains.o和ipfwadm.o模块。把其中一个加载到你的内核（注意：他们和ip_tables.o不兼容）。然后你就可以像以前那样使用ipchains和ipfwadm了。</td></tr><tr><td>这在一段时间内仍然被支持。我认为合理的计算方式是 2*(替代发布 - 初始的稳定版本），超过了这个时间，就应当使用替代的稳定版本了。这意味着在Linux 2.6或2.8中对它们的支持很可能被放弃。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">9.  <a name="mix">NAT和包过滤的混合使用</a></td></tr><tr><td>想要做网络地址转换（参见NAT HowTo)和包过滤的已很常见。好消息是他们可以混合起来使用的，而且工作得非常好。</td></tr><tr><td>你可以完全忽略你的NAT，来定义你的包过滤。包过滤看见的包的源及目标是“真正”的源和目标。例如，如果你将任何发往
1.2.3.4
80端口的包DNAT到10.1.1.1的8080端口。包过滤器看见的是包发往10.1.1.1的8080端口（真正的目的地），而非1.2.3.4
的80端口。同样，你可以忽略伪装：看到的是包的真实外部IP地址（如10.1.1.1），而响应的则返回到那里。</td></tr><tr><td>你可以使用'state'匹配扩展，使包过滤器不需要做任何额外的工作，因为无论如何，NAT都会要求连接跟踪。扩展NAT HowTo中简单的伪装例子，以禁止任何来自ppp0接口的新的连接，你可以这样：</td></tr><tr><td> #对送至ppp0的包进行伪装</td></tr><tr><td>iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE</td></tr><tr><td># 禁止由ppp0进入的新的或不合适的包</td></tr><tr><td>iptables -A INPUT -i ppp0 -m state --state NEW,INVALID -j DROP</td></tr><tr><td>iptables -A FORWARD -i ppp0 -m state --state NEW,INVALID -j DROP</td></tr><tr><td># 开启IP转发</td></tr><tr><td>echo 1 &gt; /proc/sys/net/ipv4/ip_forward</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">10.  <a name="difference">iptables和ipchains之间的差别</a></td></tr><tr><td>o  首先，内建链的名称从小写改成了大写，因为现在的INPUT和OUTPUT链只获取指向本地和本地生成的包。他们用来检查所有进入和发送的包。</td></tr><tr><td>o  '-i'标志现在表示进入接口的意思，而且只适用于INPUT和FORWORD链。FORWORD或OUTPUT链中的规则应该将'-i'改为'-o'。</td></tr><tr><td>o TCP和UDP端口现在必须用--source-port或--sport（或者--destination-port/--dport）拼写，而且必须放在'-p tcp'或'-p udp'选项之后，因为TCP或UDP扩展是分别加载的。</td></tr><tr><td>o TCP -y 标志现在是 --syn，而且必须在'-p tcp'之后。</td></tr><tr><td>o DENY目标现在是DROP.</td></tr><tr><td>o 对单个链，可以在列出其工作同时清零。</td></tr><tr><td>o 清空内建链同时清除了原则计数器。</td></tr><tr><td>o 列出链给出的是一个计数器的微型的快照。</td></tr><tr><td>o REJECT和LOG现在是扩展目标，意思是他们是独立的内核模块。</td></tr><tr><td>o 链的名称最多可以是31个字符。</td></tr><tr><td>o MASQ现在是MASQUERADE而且使用不同的语法。REDRIRECT，在保留相同的名字时，也经历了语法的改变。参见NAT-HOWTO以获取配置它们的更多信息。</td></tr><tr><td>o -o选项不再用于将包传递给用户空间设备了（见上面的-i）。现在通过 QUEUE目标传递到用户空间。</td></tr><tr><td>o 很可能还有一些我也忘了。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="name">11.  <a name="advice">对制定包过滤器的建议</a></td></tr><tr><td>在计算机安全领域中，最明智的办法是阻挡所有东西，然后对需要的开启。这通常称为“凡是没有明确允许的都是禁止的”。我建议这样做如果安全是你最关心的。</td></tr><tr><td>不要运行任何你不需要的服务，即使你认为你已经阻碍了对它们的访问。</td></tr><tr><td> 如果你创建专用防火墙，开始时不运行任何东西，并阻止所有包，然后添加服务并让需要的包通过。</td></tr><tr><td>我强调安全：结合tcp-wrappers（对于包过滤器本身的连接），代理（通过包过滤器的连接），路由验证和包过滤。路
由验证是如果包来自未预期的接口那么将被删除：例如，如果你的内部网络地址是10.1.1.0/24，而一个包的源地址是你的外部接口，那么它将被丢弃。
对一个接口如ppp0来说可以这样：</td></tr><tr><td># echo 1 &gt; /proc/sys/net/ipv4/conf/ppp0/rp_filter</td></tr><tr><td>或者对所有已有的或将有的接口：</td></tr><tr><td> # for f in /proc/sys/net/ipv4/conf/*/rp_filter; do</td></tr><tr><td># echo 1 &gt; $f</td></tr><tr><td># done</td></tr><tr><td>Debian在可能的范围了将这些设为默认。如果你使用非对称路由（如你期望包来自一个其他的方向），你可能需要在这些接口上禁止这一过滤。</td></tr><tr><td>记录对于当工作不正常时设置防火墙非常有用，但是在一个作为产品的防火墙上，总是应当将它与'limit'匹配结合，以防止有人充斥你的记录。</td></tr><tr><td>我极力推荐对安全系统使用连接追踪：它虽然会造成负担，因为所有连接都被追踪。但是对于控制对你的网络的访问非常有用。如果
你的内核没有自动加载而且没有内建，你需要加载'ip_conntrack.o'这个模块。如果想要精确追踪复杂的协议，你需要加载合适的相关模块（如
'ip_conntrack_ftp.o'）。</td></tr><tr><td># iptables -N no-conns-from-ppp0</td></tr><tr><td># iptables -A no-conns-from-ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT</td></tr><tr><td># iptables -A no-conns-from-ppp0 -m state --state NEW -i ! ppp0 -j ACCEPT</td></tr><tr><td># iptables -A no-conns-from-ppp0 -i ppp0 -m limit -j LOG --log-prefix "Bad packet from ppp0:"</td></tr><tr><td># iptables -A no-conns-from-ppp0 -i ! ppp0 -m limit -j LOG --log-prefix "Bad packet not from ppp0:"</td></tr><tr><td># iptables -A no-conns-from-ppp0 -j DROP</td></tr><tr><td> </td></tr><tr><td># iptables -A INPUT -j no-conns-from-ppp0</td></tr><tr><td># iptables -A FORWARD -j no-conns-from-ppp0</td></tr><tr><td>建造一个好的防火墙超越了这个HOWTO的范围，不过我的建议是“一切从严”。请参见Security HOWTO获取更多信息，来测试和探索你的服务器。</td></tr><tr><td class="i0"><hr /></td></tr><tr><td class="center">all pages ended here.</td></tr></tbody></table></td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/schkui/aggbug/18738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-11-01 17:49 <a href="http://www.cnitblog.com/schkui/archive/2006/11/01/18738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vim/Cscope,Ctags</title><link>http://www.cnitblog.com/schkui/archive/2006/10/23/18291.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Mon, 23 Oct 2006 10:15:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/10/23/18291.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/18291.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/10/23/18291.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/18291.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/18291.html</trackback:ping><description><![CDATA[
		<p>今天试着配置了一下Cscope，用起来确实蛮方便的，如果和Ctags配合使用的好的话，的确可以和windows平台下的sourceinsight有的一拼。不过这个熟练的过程不会太轻松:-|</p>
		<h2>
				<a name="hd001001">
				</a>cscope</h2>
		<p>cscope应该不需要安装，一般linux的发行版都会带的有(也有可能是vim的dependence
package，这个我没有研究)，在shell下输入cscope -V可以查看cscope的版本号，我这边是15.5。</p>
		<ul>
				<li class="asterisk">
        cscope的配置和简单使用可以参考:<a href="http://cscope.sourceforge.net/cscope_vim_tutorial.html" class="remote">The
        Vim/Cscope tutorial</a><a name="idx001"></a>，貌似还没有简体翻译版本，看了一下确实很简单，所以没人翻译啦。
    </li>
				<li class="asterisk">

        还有就是man cscope(under shell)和:help cscope(in vim)
    </li>
		</ul>
		<p>我配完之后有一个小问题:Cscope里对split window query
mode的键盘绑定是Ctrl-Blankspace，对于中文用户来说，这一般也是中文输入法的short-key。这就需要修改
~/.vim/plugin/cscope_maps.vim文件，把其中对ctrl+blankspace(在vim中表示为ctrl+@)的绑定修改
为你特性的组合键。</p>
		<h2>
				<a name="hd001002">
				</a>ctags</h2>
		<p>
				<a href="http://ctags.sourceforge.net/" class="remote">ctags</a>
				<a name="idx002">
				</a>可以在sf的站点上下载，编译安装后就可以使用了。</p>
		<p>简单的使用方法是：</p>
		<ul>
				<li class="asterisk">
        在你存放源代码的文件夹下运行ctags *，即对所有问题件做tag
    </li>
				<li class="asterisk">
        此时，用vim -t funcname就可以直接用vim打开含有funcname函数的文件，光标也停留在该文件
    </li>
				<li class="asterisk">
        在vim中，使用&lt;ctrl+]&gt;可以跳转到光标所在位置的函数实现(类似于vim帮助中的调准)，使用&lt;ctrl+T&gt;可以跳转回之前的光标位置。
    </li>
		</ul>
		<h2>
				<a name="hd001003">
				</a>其他参考资料</h2>
		<ul>
				<li class="asterisk">
						<a href="http://www.chinalinuxpub.com/read.php?wid=21" class="remote">Introduc-tion
        to Programming in C/C++ with Vim</a>
						<a name="idx003">
						</a> (中英文)
    </li>
				<li class="asterisk">
						<a href="http://ctags.sourceforge.net/faq.html" class="remote">Exuberant
        Ctags FAQ</a>
				</li>
		</ul>
<img src ="http://www.cnitblog.com/schkui/aggbug/18291.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-10-23 18:15 <a href="http://www.cnitblog.com/schkui/archive/2006/10/23/18291.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ssh的安全限制</title><link>http://www.cnitblog.com/schkui/archive/2006/10/10/17820.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Tue, 10 Oct 2006 03:06:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/10/10/17820.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/17820.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/10/10/17820.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/17820.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/17820.html</trackback:ping><description><![CDATA[适应操作系统：redhat<br /><br />如果要正常使用ssh客户端和ssh服务，需要安装一个server和client<br /><br />1。重新启动sshd<br /><br />引文:<br />    /etc/init.d/sshd restart<br />2。限制root远程登录<br /><br />往往有些不怀好心的人想通过暴力破解来获取系统的id，如果被他们获得root用户的id，那是非常危险的，所以我们除了限制ssh的ip段外，还可以限制root远程登录来达到一定的安全保障<br /><br />引文:<br />    vi /etc/ssh/sshd_config<br /><br />ESC /#PermitRootLogin yes<br /><br />修改为PermitRootLogin no<br />记得把#去掉<br /><br />改好以后，我们按照上面的方法重新启动sshd<br /><br />3。限制远程登录的ip地址<br /><br />这里，我们可以修改/etc/hosts.allow，也可以修改/etc/hosts.deny<br />一般情况下，我们在/etc/hosts.deny里头禁止掉所有的用户，内容如下<br /><br />引文:<br />       sshd:ALL@ALL:spawn /bin/echo `date` %c &gt;&gt; /var/log/tcp_wrapper<br />然后在/etc/hosts.allow文件里头设置允许的ip段或者是ip地址<br />例如：<br />引文:<br />       sshd: 202.201.0.0/255.255.255.0,202.201.177.90<br />这样的效果是允许202.201.0.0的这个C类网路的所有用户和202.201.177.90这个用户拉<br /><br />重新按照上面的方法重新启动sshd使之生效<br /><img src ="http://www.cnitblog.com/schkui/aggbug/17820.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-10-10 11:06 <a href="http://www.cnitblog.com/schkui/archive/2006/10/10/17820.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tcpdump命令的使用与示例——linux下的网络分析</title><link>http://www.cnitblog.com/schkui/archive/2006/10/10/17816.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Tue, 10 Oct 2006 01:36:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/10/10/17816.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/17816.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/10/10/17816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/17816.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/17816.html</trackback:ping><description><![CDATA[
		<p>网络数据采集分析工具TcpDump的简介</p>
		<p>顾名思义，TcpDump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤，并提供and、or、not等逻辑语句来帮助你去掉无用的信息。<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>就是一种免费的网络分析工具，尤其其提供了源代码，公开了接口，因此具备很强的可扩展性，对于网络维护和入侵者都是非常有用的工具。<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>存在于基本的FreeBSD系统中，由于它需要将网络界面设置为混杂模式，普通用户不能正常执行，但具备root权限的用户可以直接执行它来获取网络上的信息。因此系统中存在网络分析工具主要不是对本机安全的威胁，而是对网络上的其他计算机的安全存在威胁。</p>
		<p>我们用尽量简单的话来定义<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>，就是：dump the traffice on a network.，根据使用者的定义对网络上的数据包进行截获的包分析工具。作为互联网上经典的的系统管理员必备工具，<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>以其强大的功能，灵活的截取策略，成为每个高级的系统管理员分析网络，排查问题等所必备的东西之一。<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>提供了源代码，公开了接口，因此具备很强的可扩展性，对于网络维护和入侵者都是非常有用的工具。<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>存在于基本的FreeBSD系统中，由于它需要将网络界面设置为混杂模式，普通用户不能正常执行，但具备root权限的用户可以直接执行它来获取网络上的信息。因此系统中存在网络分析工具主要不是对本机安全的威胁，而是对网络上的其他计算机的安全存在威胁。 </p>
		<p>网络数据采集分析工具TcpDump的安装</p>
		<div class="content">
				<marquee width="1" height="27">
						<a href="http://anheng.com.cn/news/24/586.html">
								<font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font>
						</a>
				</marquee> 在<a href="http://linux.anheng.com.cn/news/24/586.html">linux</a>下<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的安装十分简单，一般由两种安装方式。一种是以rpm包的形式来进行安装。另外一种是以源程序的形式安装。<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> rpm包的形式安装：这种形式的安装是最简单的安装方法，rpm包是将软件编译后打包成二进制的格式，通过rpm命令可以直接安装，不需要修改任何东西。以超级用户登录，使用命令如下：<br />#rpm -ivh <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>-3_4a5.rpm<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> 这样<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>就顺利地安装到你的<a href="http://linux.anheng.com.cn/news/24/586.html">linux</a>系统中。怎么样，很简单吧。
<p>源程序的安装：既然rpm包的安装很简单,为什么还要采用比较复杂的源程序安装呢?其实，<a href="http://linux.anheng.com.cn/news/24/586.html">linux</a>一个最大的诱人之处就是在她上面有很多软件是提供源程序的，人们可以修改源程序来满足自己的特殊的需要。所以我特别建议朋友们都采取这种源程序的安装方法。</p><ul><li>第一步 取得源程序 在源程序的安装方式中，我们首先要取得<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的源程序分发包，这种分发包有两种形式，一种是tar压缩包(<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>-3_4a5.tar.Z),另一种是rpm的分发包(<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>-3_4a5.src.rpm)。这两种形式的内容都是一样的，不同的仅仅是压缩的方式.tar的压缩包可以使用如下命令解开：<br />#tar xvfz <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>-3_4a5.tar.Z<br />rpm的包可以使用如下命令安装:<br />#rpm -ivh <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>-3_4a5.src.rpm<br />这样就把<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的源代码解压到/usr/src/redhat/SOURCES目录下. <br /></li><li>第二步 做好编译源程序前的准备活动<br />在编译源程序之前，最好已经确定库文件libpcap已经安装完毕，这个库文件是<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>软件所需的库文件。同样，你同时还要有一个标准的c语言编译器。在<a href="http://linux.anheng.com.cn/news/24/586.html">linux</a>下标准的c 语言编译器一般是gcc。 在<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的源程序目录中。有一个文件是Makefile.in，configure命令就是从Makefile.in文件中自动产生Makefile文件。在Makefile.in文件中，可以根据系统的配置来修改BINDEST 和 MANDEST 这两个宏定义，缺省值是<br />BINDEST = @sbindir@ <br />MANDEST = @mandir@<br />第一个宏值表明安装<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的二进制文件的路径名，第二个表明<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的man 帮助页的路径名,你可以修改它们来满足系统的需求。<br /></li><li>第三步 编译源程序<br />使用源程序目录中的configure脚本，它从系统中读出各种所需的属性。并且根据Makefile.in文件自动生成Makefile文件，以便编译使用.make 命令则根据Makefile文件中的规则编译<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的源程序。使用make install命令安装编译好的<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的二进制文件。<br />总结一下就是:<br /># tar xvfz <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>-3_4a5.tar.Z<br /># vi Makefile.in<br /># . /configure<br /># make<br /># make install</li></ul><p>3 网络数据采集分析工具TcpDump的使用</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>     普通情况下，直接启动<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>将监视第一个网络界面上所有流过的数据包。<br /><font face="courier new, courier, mono"># <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a><br /><a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>: listening on fxp0<br />11:58:47.873028 202.102.245.40.netbios-ns &gt; 202.102.245.127.netbios-ns: udp 50<br />11:58:47.974331 0:10:7b:8:3a:56 &gt; 1:80:c2:0:0:0 802.1d ui/C len=43<br />                         0000 0000 0080 0000 1007 cf08 0900 0000<br />                         0e80 0000 902b 4695 0980 8701 0014 0002<br />                         000f 0000 902b 4695 0008 00<br />11:58:48.373134 0:0:e8:5b:6d:85 &gt; Broadcast sap e0 ui/C len=97<br />                         ffff 0060 0004 ffff ffff ffff ffff ffff<br />                         0452 ffff ffff 0000 e85b 6d85 4008 0002<br />                         0640 4d41 5354 4552 5f57 4542 0000 0000<br />                         0000 00<br />^C</font><p>    <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>支持相当多的不同参数，如使用-i参数指定<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>监听的网络界面，这在计算机具有多个网络界面时非常有用，使用-c参数指定要监听的数据包数量，使用-w参数指定将监听到的数据包写入文件中保存，等等。</p><p>    然而更复杂的<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>参数是用于过滤目的，这是因为网络中流量很大，如果不加分辨将所有的数据包都截留下来，数据量太大，反而不容易发现需要的数据包。使用这些参数定义的过滤规则可以截留特定的数据包，以缩小目标，才能更好的分析网络中存在的问题。<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>使用参数指定要监视数据包的类型、地址、端口等，根据具体的网络问题，充分利用这些过滤规则就能达到迅速定位故障的目的。请使用man <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>查看这些过滤规则的具体用法。</p><p>   
显然为了安全起见，不用作网络管理用途的计算机上不应该运行这一类的网络分析软件，为了屏蔽它们，可以屏蔽内核中的bpfilter伪设备。一般情况下网
络硬件和TCP/IP堆栈不支持接收或发送与本计算机无关的数据包，为了接收这些数据包，就必须使用网卡的混杂模式，并绕过标准的TCP/IP堆栈才行。
在FreeBSD下，这就需要内核支持伪设备bpfilter。因此，在内核中取消bpfilter支持，就能屏蔽<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>之类的网络分析工具。</p><p>    并且当网卡被设置为混杂模式时，系统会在控制台和日志文件中留下记录，提醒管理员留意这台系统是否被用作攻击同网络的其他计算机的跳板。</p><p>    May 15 16:27:20 host1 /kernel: fxp0: promiscuous mode enabled</p><p>   
虽然网络分析工具能将网络中传送的数据记录下来，但是网络中的数据流量相当大，如何对这些数据进行分析、分类统计、发现并报告错误却是更关键的问题。网络
中的数据包属于不同的协议，而不同协议数据包的格式也不同。因此对捕获的数据进行解码，将包中的信息尽可能的展示出来，对于协议分析工具来讲更为重要。昂
贵的商业分析工具的优势就在于它们能支持很多种类的应用层协议，而不仅仅只支持tcp、udp等低层协议。</p><p>    从上面<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的输出可以看出，<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>对截获的数据并没有进行彻底解码，数据包内的大部分内容是使用十六进制的形式直接打印输出的。显然这不利于分析网络故障，通常的解决办法是先使用带-w参数的<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> 截获数据并保存到文件中，然后再使用其他程序进行解码分析。当然也应该定义过滤规则，以避免捕获的数据包填满整个硬盘。FreeBSD提供的一个有效的解码程序为tcpshow，它可以通过Packages Collection来安装。</p><p><font face="courier new, courier, mono"># pkg_add /cdrom/packages/security/tcpshow*<br /># <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> -c 3 -w <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>.out<br /><a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>: listening on fxp0<br /># tcpshow &lt; <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>.out<br />---------------------------------------------------------------------------<br />Packet 1<br />TIME:12:00:59.984829<br />LINK:00:10:7B:08:3A:56 -&gt; 01:80:C2:00:00:00 type=0026<br />&lt;*** No decode support for encapsulated protocol ***&gt;<br />---------------------------------------------------------------------------<br />Packet 2<br />TIME:12:01:01.074513 (1.089684)<br />LINK:00:A0:C9:AB:3C:DF -&gt; FF:FF:FF:FF:FF:FF type=ARP<br />ARP:htype=Ethernet ptype=IP hlen=6 plen=4 op=request<br />sender-MAC-addr=00:A0:C9:AB:3C:DF sender-IP-address=202.102.245.3<br />target-MAC-addr=00:00:00:00:00:00 target-IP-address=202.102.245.3<br />---------------------------------------------------------------------------<br />Packet 3<br />TIME:12:01:01.985023 (0.910510)<br />LINK:00:10:7B:08:3A:56 -&gt; 01:80:C2:00:00:00 type=0026<br />&lt;*** No decode support for encapsulated protocol ***&gt;</font></p><p>    tcpshow能以不同方式对数据包进行解码，并以不同的方式显示解码数据，使用者可以根据其手册来选择最合适的参数对截获的数据包进行分析。从上面的例子中可以看出，tcpshow支持的协议也并不丰富，对于它不支持的协议就无法进行解码。</p><p>    除了<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>之
外，FreeBSD的Packages
Collecion中还提供了Ethereal和Sniffit两个网络分析工具，以及其他一些基于网络分析方式的安全工具。其中Ethereal运行在
X Window 下，具有不错的图形界面，Sniffit使用字符窗口形式，同样也易于操作。然而由于<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>对
过滤规则的支持能力更强大，因此系统管理员仍然更喜欢使用它。对于有经验的网络管理员，使用这些网络分析工具不但能用来了解网络到底是如何运行的，故障出
现在何处，还能进行有效的统计工作，如那种协议产生的通信量占主要地位，那个主机最繁忙，网络瓶颈位于何处等等问题。因此网络分析工具是用于网络管理的宝
贵系统工具。为了防止数据被滥用的网络分析工具截获，关键还是要在网络的物理结构上解决。常用的方法是使用交换机或网桥将信任网络和不信任网络分隔开，可
以防止外部网段窃听内部数据传输，但仍然不能解决内部网络与外部网络相互通信时的数据安全问题。如果没有足够的经费将网络上的共享集线器升级为以太网交换
机，可以使用FreeBSD系统执行网桥任务。这需要使用option BRIDGE编译选项重新定制内核，此后使用bridge命令启动网桥功能。</p><p><font face="courier new, courier, mono"><a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>采用命令行方式，它的命令格式为：<br />    　　<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ]<br />　　　　　　　　　　[ -i 网络接口 ] [ -r 文件名] [ -s snaplen ]<br />　　　　　　　　　　[ -T 类型 ] [ -w 文件名 ] [表达式 ]<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> </font></p><font face="courier new, courier, mono">(1). <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的选项介绍<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> 　　　-a 　　　将网络地址和广播地址转变成名字；<br />　　　-d 　　　将匹配信息包的代码以人们能够理解的汇编格式给出；<br />　　　-dd 　　 将匹配信息包的代码以c语言程序段的格式给出；<br />　　　-ddd 　　将匹配信息包的代码以十进制的形式给出；<br />　　　-e 　　　在输出行打印出数据链路层的头部信息；<br />　　　-f 　　　将外部的Internet地址以数字的形式打印出来；<br />　　　-l 　　　使标准输出变为缓冲行形式；<br />　　　-n 　　　不把网络地址转换成名字；<br />　　　-t 　　　在输出的每一行不打印时间戳；<br />　　　-v 　　　输出一个稍微详细的信息，例如在ip包中可以包括ttl和服务类型的信息；<br />　　　-vv 　　 输出详细的报文信息；<br />　　　-c 　　　在收到指定的包的数目后，<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>就会停止；<br />　　　-F 　　　从指定的文件中读取表达式,忽略其它的表达式；<br />　　　-i 　　　指定监听的网络接口；<br />　　　-r 　　　从指定的文件中读取包(这些包一般通过-w选项产生)；<br />　　　-w 　　　直接将包写入文件中，并不分析和打印出来；<br />　　　-T 　　　将监听到的包直接解释为指定的类型的报文，常见的类型有rpc （远程过程调用）和snmp（简单网络管理协议；）</font><p>(2). <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的表达式介绍</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>     表达式是一个正则表达式，<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>利用它作为过滤报文的条件，如果一个报文满足表达式的条件，则这个报文将会被捕获。如果没有给出任何条件，则网络上所有的信息包将会被截获。在表达式中一般如下几种类型的关键字。<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>    
第一种是关于类型的关键字，主要包括host，net，port, 例如 host 210.27.48.2，指明
210.27.48.2是一台主机，net 202.0.0.0 指明 202.0.0.0是一个网络地址，port 23
指明端口号是23。如果没有指定类型，缺省的类型是host.<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>    
第二种是确定传输方向的关键字，主要包括src , dst ,dst or src, dst and src
,这些关键字指明了传输的方向。举例说明，src 210.27.48.2 ,指明ip包中源地址是210.27.48.2 , dst net
202.0.0.0 指明目的网络地址是202.0.0.0 。如果没有指明方向关键字，则缺省是src or dst关键字。<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>    
第三种是协议的关键字，主要包括fddi,ip,arp,rarp,tcp,udp等类型。Fddi指明是在FDDI(分布式光纤数据接口网络)上的特定
的网络协议，实际上它是"ether"的别名，fddi和ether具有类似的源地址和目的地址，所以可以将fddi协议包当作ether的包进行处理和
分析。其他的几个关键字就是指明了监听的包的协议内容。如果没有指定任何协议，则<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>将会监听所有协议的信息包。
<p>    除了这三种类型的关键字之外，其他重要的关键字如下：gateway,
broadcast,less,greater,还有三种逻辑运算，取非运算是 'not ' '! ',
与运算是'and','&amp;&amp;';或运算 是'or'
,'││'；这些关键字可以组合起来构成强大的组合条件来满足人们的需要，下面举几个例子来说明。</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>     A想要截获所有210.27.48.1 的主机收到的和发出的所有的数据包：<br />#<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> host 210.27.48.1 <br />B想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信，使用命令：（在命令行中适用　　　括号时，一定要<br />#<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \) <br />C如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包，使用命令：<br />#<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> ip host 210.27.48.1 and ! 210.27.48.2<br />D如果想要获取主机210.27.48.1接收或发出的telnet包，使用如下命令：<br />#<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> tcp port 23 host 210.27.48.1 
<p>(3). <a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>的输出结果介绍</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>     下面我们介绍几种典型的<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a>命令的输出信息<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> A,数据链路层头信息<marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> 使用命令<br />#<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> --e host ice<br />ice 是一台装有<a href="http://linux.anheng.com.cn/news/24/586.html">linux</a>的主机，她的MAC地址是0：90：27：58：AF：1A<br />H219是一台装有SOLARIC的SUN工作站，它的MAC地址是8：0：20：79：5B：46；上一条命令的输出结果如下所示：<br />21:50:12.847509 eth0 &lt; 8:0:20:79:5b:46 0:90:27:58:af:1a ip 60: h219.33357 &gt; ice.telne<br />t 0:0(0) ack 22535 win 8760 (DF)
<p>    分析：21：50：12是显示的时间， 847509是ID号，eth0 &lt;表示从网络接口eth0 接受该数据包，eth0
&gt;表示从网络接口设备发送数据包, 8:0:20:79:5b:46是主机H219的MAC地址,它表明是从源地址H219发来的数据包.
0:90:27:58:af:1a是主机ICE的MAC地址,表示该数据包的目的地址是ICE . ip 是表明该数据包是IP数据包,60
是数据包的长度, h219.33357 &gt; ice.telnet
表明该数据包是从主机H219的33357端口发往主机ICE的TELNET(23)端口. ack 22535
表明对序列号是222535的包进行响应. win 8760表明发送窗口的大小是8760.</p><p>B,ARP包的TCPDUMP输出信息</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee> 使用命令<br />#<a href="http://tcpdump.anheng.com.cn/news/24/586.html">tcpdump</a> arp <br />得到的输出结果是：<br />22:32:42.802509 eth0 &gt; arp who-has route tell ice (0:90:27:58:af:1a)<br />22:32:42.802902 eth0 &lt; arp reply route is-at 0:90:27:12:10:66 (0:90:27:58:af:1a)<br />分
析: 22:32:42是时间戳, 802509是ID号, eth0 &gt;表明从主机发出该数据包, arp表明是ARP请求包,
who-has route tell ice表明是主机ICE请求主机ROUTE的MAC地址。
0:90:27:58:af:1a是主机ICE的MAC地址。
<p>C,TCP包的输出信息</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>     用TCPDUMP捕获的TCP包的一般输出信息是：<br />src &gt; dst: flags data-seqno ack window urgent options<br />src
&gt; dst:表明从源地址到目的地址, flags是TCP包中的标志信息,S 是SYN标志, F (FIN), P (PUSH) , R
(RST) "." (没有标记); data-seqno是数据包中的数据的顺序号, ack是下次期望的顺序号,
window是接收缓存的窗口大小, urgent表明数据包中是否有紧急指针. Options是选项.
<p>D,UDP包的输出信息</p><marquee width="1" height="27"><a href="http://anheng.com.cn/news/24/586.html"><font color="#eeeeee">http://anheng.com.cn/news/24/586.html</font></a></marquee>     用TCPDUMP捕获的UDP包的一般输出信息是：<br />route.port1 &gt; ice.port2: udp lenth<br />UDP十分简单，上面的输出行表明从主机ROUTE的port1端口发出的一个UDP数据包到主机ICE的port2端口，类型是UDP， 包的长度是lenth</div>
<img src ="http://www.cnitblog.com/schkui/aggbug/17816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-10-10 09:36 <a href="http://www.cnitblog.com/schkui/archive/2006/10/10/17816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载: 用红帽子的chkconfig管理Init脚本</title><link>http://www.cnitblog.com/schkui/archive/2006/05/29/11184.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Mon, 29 May 2006 06:41:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/05/29/11184.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/11184.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/05/29/11184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/11184.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/11184.html</trackback:ping><description><![CDATA[
[OpenSource] 用红帽子的chkconfig管理Init脚本<div>
作者：Jimmy Ball			<br />
译者：Fenng	        <br />
日期：11-Dec-2001	<br />
出处：http://www.dbanotes.net<br />
版本：0.99	<br /></div><hr /><p>
你的管理工具中多了个简单但非常有用的东东。 
</p><p>
我喜欢发现新的 UNIX 命令，尤其是那些关于系统管理的。当我得知红帽子发布 chkconfig 
这个工具，我想起了在 IRIX --一个从 <acronym title="Silicon Graphics Inc.">SGI</acronym>而来的 UNIX 变种--下的 
chkconfig。IRIX 的 chkconfig 用来激活/禁止系统初始化的时候的服务，无需编辑，重命名或是移动 
 /etc 中的 init 脚本。 </p><p>
类似，Red Hat 设计 chkconfig 的目的就是用来管理系统初始化的时候启动的服务。不过，在我仔细阅读
手册并作了些测试后，我很快发现 Red Hat 扩展了chkconfig，通过管理 init 脚本的符号连接得以最终控制启动关闭时的系统任务，
真是节省时间！ 
</p><h2>关于启动的基础知识 </h2><p>当你的 linux 启动时, 它显示的第一个进程是 init 。如果你以前没看到过显示 init 进程, 
输入：</p><blockquote><pre># ps -ef | grep init <br /></pre></blockquote>
就会看到 init 的 PID。 简而言之，init 运行 /etc/inittab 中描述的任务。 
<p>
/etc/inittab中说明的任务在init之后就会启动， 
不过其它的任务启动很简单。例如，默认情况下 Red Hat 的 /etc/inittab 
对 Ctrl-Alt-Delete 键序设置了一个 trap，当这些键在控制台模式下（不是 xdm）同
时按下 ，就会运行 shutdown 命令。 在启动的时候，init 基于 /etc/inittab  
的设置选项设定这个特性，不过在这个键序发生的时候才会执行。 
</p>
inittab 的格式允许以"#"开始注释行，正常的条目用 ":" 界定。遵从如下的格式： 
<blockquote><pre>id:runlevel:action:process <br /></pre></blockquote><blockquote><table><tbody><tr><td>id </td><td>代表用户定义的唯一的标志</td></tr><tr><td>runlevel </td><td>可以使0-6的组合 或者为空</td></tr><tr><td>action </td><td>来自一个关键词keyword 描述init如何对待process</td></tr><tr><td>process </td><td>是要执行的命令</td></tr></tbody></table></blockquote><p>
描述 action 字段的各种关键字可以在 inittab 的手册中找到。常用的关键字，不是全部，UNIX 平台包括这些: 
</p><blockquote><table><tbody><tr><td>initdefault</td><td>定义一个系统启动后进入的运行级</td></tr><tr><td>wait</td><td>会被执行一次的进程 (当进入运行级的时候)。init 进程将等待这个进程被终止</td></tr><tr><td>boot</td><td>定义一个启动的时候执行的进程</td></tr><tr><td>bootwait</td><td>与 boot 类似 ，不过 init在继续运行前等待进程的终止</td></tr><tr><td>sysinit</td><td>定义一个进程在 boot的时候执行，在任何 boot或者bootwait inittab 
条目的前面执行。</td></tr></tbody></table></blockquote><p>
runlevel 字段指明系统状态。例如，运行级 0 代表系统关机，运行级 6 代表系统重启 
。不幸的是，不是所有的 Linux 发布都遵循同样的运行级定义 。在 Red 
Hat 中，默认情况下支持下面这些 </p><blockquote>
0. 系统挂起 <br />
1. 但用户Single-user mode  <br />
2. 多用户，没有NFS  <br />
3. 完整的多用户Complete multiuser mode  <br />
4. 用户自定义  <br />
5. X11 (XDM 登录)  <br />
6. 重新启动  <br /></blockquote><p>
每一个运行级在 /etc/rc.d 下都有个相应的目录。如运行级 5，目录就是 /etc/rc.d/rc5.d 
。包含启动这个运行级的时候运行的相关任务的相关文件。在 Red Hat 中, 
这些文件一般都是 shell 脚本的符号连接，可以在 /etc/rc.d/init.d 中找到。 
</p><p>
让我们用一个简单的例子看一下这些东西， 下面这两个例子行来自我们的 inittab 文件： 
</p><blockquote><pre>id:3:initdefault: <br />l3:3:wait:/etc/rc.d/rc 3 <br /></pre></blockquote><p>
在 Red Hat 系统中这很典型。一旦 init 被启动 ，读取 /etc/inittab 。 
从第一行，我们知道 init 将在系统启动后从运行运行级3。一旦我们到了那个运行级 
，第二行告诉 init 去运行脚本 /etc/rc.d/rc 3 并且在执行前等待终止。 
</p><p>
在 /etc/rc.d 目录的 rc 脚本收到 3 作为一个参数。 这个 3 相当于运行级 3。结果 rc 
脚本执行 /etc/rc.d/rc3.d 目录中的所有脚本。它首先用参数 "stop" 执行所有 K（代表 
"kill"杀掉进程或者服务）打头的脚本，接下来，它运行所有以字母 S 
打头的脚本，带有参数 "start" 启动进程或者服务。 
最后要指明，K 和 S 脚本的执行顺序是基于排序的；名为 S90mysql 的脚本将在 
S95httpd 之前执行。 
</p><p>
/etc/rc.d/rc3.d 
中的脚本实际是对 /etc/rc.d/init.d 中文件的符号连接。UNIX管理员可以在rc3.d中放制文
件， 实际情况下 Red Hat 的 init.d 目录是所有脚本的第一位置，然后生成逻辑连接到 rc*.d 
目录。手工进行这些文件的管理很烦人、琐碎。 chkconfig 现在接手这件事情! Red Hat 
的这个 chkconfig 工具就是专为管理 /etc/rc.d/rc[0-6].d 中的符号连接而设计。 
</p><h2>
察看 chkconfig 的项（Entry） </h2><p>
chkconfig 的二进制软件在 /sbin 下，默认权限允许任何用户执行。不过没有 root 权限的用户只能察看当前的 chkconfig 配置。输入： 
</p><blockquote><pre>[root]# chkconfig --list | grep on <br /></pre></blockquote><p>
输出的部分内容大致如下： </p><blockquote><pre>gpm             0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />syslog          0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />network         0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />random          0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />rawdevices      0:off   1:off   2:off   3:on    4:on    5:on    6:off<br />atd             0:off   1:off   2:off   3:on    4:on    5:on    6:off<br />apmd            0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />sendmail        0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />sshd            0:off   1:off   2:on    3:off   4:on    5:on    6:off<br />portmap         0:off   1:off   2:off   3:off   4:on    5:on    6:off<br />crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off<br />xinetd          0:off   1:off   2:off   3:on    4:on    5:on    6:off<br />xfs             0:off   1:off   2:on    3:off   4:on    5:on    6:off<br />httpd           0:off   1:off   2:off   3:on    4:off   5:off   6:off<br /></pre></blockquote><p>
在输出的每一行，最开始的段代表在 /etc/rc.d/init.d 中的 init 脚本名。 
其余的区段表示脚本进入各个运行级时的各运行级 0-6 的状态。 
例如，crond 应当在进入运行级 2、3、4、5 的时候启动，当进入 0、1、
6的时候停止。我们可以通过 find 命令查找在 /etc/rc.d 中所有 crond 结尾的文件确信我们设
置的正确性：</p><blockquote><pre>[root]# find /etc/rc.d -name '*crond' -print <br />/etc/rc.d/init.d/crond <br />/etc/rc.d/rc0.d/K60crond <br />/etc/rc.d/rc1.d/K60crond <br />/etc/rc.d/rc2.d/S40crond <br />/etc/rc.d/rc3.d/S40crond <br />/etc/rc.d/rc4.d/S40crond <br />/etc/rc.d/rc5.d/S40crond <br />/etc/rc.d/rc6.d/K60crond <br /></pre></blockquote>
注意 chkconfig 报告的每个 "off" 节 (0, 1, 6)， 一个 kill 脚本存在 script is in 
place 每一个 "on" 节 (2, 3, 4, 5)，有一个 start 脚本。接下来，执行一个不同的 
find 命令以确信每个发现的文件的类型： 
<blockquote><pre>[root]# find /etc/rc.d -name '*crond' -exec file {} ; <br />/etc/rc.d/init.d/crond: Bourne shell script text <br />/etc/rc.d/rc0.d/K60crond: symbolic link to <br />../init.d/crond <br />/etc/rc.d/rc1.d/K60crond: symbolic link to <br />../init.d/crond <br />/etc/rc.d/rc2.d/S40crond: symbolic link to <br />../init.d/crond <br />/etc/rc.d/rc3.d/S40crond: symbolic link to <br />../init.d/crond <br />/etc/rc.d/rc4.d/S40crond: symbolic link to <br />../init.d/crond <br />/etc/rc.d/rc5.d/S40crond: symbolic link to <br />../init.d/crond <br />/etc/rc.d/rc6.d/K60crond: symbolic link to <br />../init.d/crond <br /></pre></blockquote><p>这表明在 init.d 中找到的 crond 是一个 shell 脚本，找到的所有其他的文件都是对 crond 
脚本的符号连接。 
</p><h2>调整 chkconfig 项</h2><p>调整 chkconfig 的项几乎和列出现在的设置一样容易。格式: 
</p><blockquote><pre>chkconfig [--level &lt;运行级&gt;] &lt;名字&gt; <br /></pre></blockquote><p>
例如，如果我们决定在运行级 2 禁止crond，</p><blockquote><pre># chkconfig --level 2 crond off <br /></pre></blockquote>
(root执行)会在运行级 2 关掉 crond。运行 chkconfig 
--list会确信crond的配置已经被调整。更进一步，下面的 find 命令显示一个 
kill 脚本已经在目录 rc2.d 中代替了 start 脚本： 
<blockquote><pre>[root]# find /etc/rc.d -name '*crond' -print <br />/etc/rc.d/init.d/crond <br />/etc/rc.d/rc0.d/K60crond <br />/etc/rc.d/rc1.d/K60crond <br />/etc/rc.d/rc2.d/K60crond <br />/etc/rc.d/rc3.d/S40crond <br />/etc/rc.d/rc4.d/S40crond <br />/etc/rc.d/rc5.d/S40crond <br />/etc/rc.d/rc6.d/K60crond <br /></pre></blockquote><p><strong>切记</strong>： 
chkconfig 不是立即自动禁止或激活一个服务的，它只是简单的改变了符号连接，超级用户
可以用这个命令 /etc/rc.d/init.d/crond 
stop 立刻禁止 crond 服务。最后，你可以用一个命令行激活/禁止多个运行级的某个命令 。 
例如输入： 
</p><blockquote><pre>chkconfig --levels 2345 crond on <br /></pre></blockquote><p>会设定 crond 在运行级2， 3， 4 和 5启动。 
</p><h2>删掉一项 </h2><p>有的时候， 
删掉一个服务也很恰当。例如，针对 sendmail，在客户机上导入本地账号的邮件没有必要。
运行 sendmail 作为守护进程就不是必要的了。这种情况，我发现禁止 sendmail 服务很有必要
，减少了潜在的安全问题，从 chkconfig 中删掉 sendmail，输入： </p><blockquote><pre>chkconfig --del sendmail <br /></pre></blockquote><p>
在下面，我们的 find 命令显示该处没有符号连接了，不过 sendmail 的 init 脚本仍然有： 
</p><blockquote><pre>[root]# find /etc/rc.d -name '*sendmail' -print <br />/etc/rc.d/init.d/sendmail<br /></pre></blockquote><p>
在我看来这很完美。脚本保留了，万一 sendmail 
需要作为一个服务实现呢？不过所有的符号连接去掉了。我们能在每一个运行级禁
止 sendmail 
服务，这将在每一个 rc*.d 子目录中放置一个 kill 脚本，虽然 sendmail 从不在初始化阶段启
动，是个不必要的任务 ，可是，我曾看到一些系统管理员需要在特定的场合手工启动服务。把 kill 脚本留在那里确保可以干净的杀掉服务。 
</p><h2>添加chkconfig 项 </h2><p>
到目前为止，一切顺利。我们已经知道使用 chkconfig 如何查看、调整、删掉服务。现在添
加一个新的服务。看下面的脚本 oracle: 
</p><blockquote><pre>Listing 1. Oracle Script<br />#!/bin/sh<br /><br />#chkconfig: 2345 80 05<br />#description: Oracle 8 Server<br /><br />ORA_HOME=/usr/home/oracle/product/8.0.5<br />ORA_OWNER=oracle<br /><br />if [ ! -f $ORA_HOME/bin/dbstart ]<br />then<br />  echo "Oracle startup: cannot start"<br />  exit<br />fi<br /><br />case "$1" in<br />  "start")<br />     su - $ORA_OWNER -c $ORA_HOME/bin/dbstart<br />     su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl start"<br />     ;;<br />  "stop")<br />     su - $ORA_OWNER -c $ORA_HOME/bin/dbshut<br />     su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl stop"<br />     ;;<br />esac<br />----------------------------------------------------- <br /></pre></blockquote><p>
使用这个脚本，Oracle 8 可以以参数 "start" 启动，以 "stop"
参数停止。它符合 init 脚本的最小要求可以和 /etc/rc.d/rc 脚本联合使用。 
</p><p>
把脚本放到 /etc/rc.d/init.d 中并运行(以 root) ： 
</p><blockquote><pre>chmod +x /etc/rc.d/init.d/oracle <br /></pre></blockquote><p>
使你的脚本可执行。如果你担心普通用户察看这个脚本，你可以设定更严格的文件权限 
。只要这个脚本可以被 root 作为单独的脚本运行就可以。 
</p><p>
注意脚本中的两行注释: </p><blockquote><pre>#chkconfig: 2345 80 05 <br />#description: Oracle 8 Server <br /></pre></blockquote><p>
chkconfig 需要这些行来决定如何实现初始运行级添加服务，如何设定启动和停止顺序的优
先级。这些行指明脚本将为运行级 2、3、4、5 启动 Oracle 8 服务。另外， 
启动优先权将被设定为 80 而停止优先权设定为 05。 
</p><p>
现在脚本在合适的位置，并且有合适的执行权限，以及恰当的 chkconfig 注释， 
我们可以添加 init 脚本，以 root 用户执行， </p><blockquote><pre># chkconfig --add oracle. <br /></pre></blockquote><p>用 chkconfig 的查询，我们能核实我们所作的添加: 
</p><blockquote><pre>[root]# chkconfig --list | grep oracle <br />oracle 0:off 1:off 2:on 3:on 4:on 5:on 6:off <br /></pre></blockquote><p>而且，我们可以用标准的 find 命令察看 chkconfig 如何设定符号连接： </p><blockquote><pre>[root]# find /etc/rc.d -name '*oracle' -print <br /><br />/etc/rc.d/init.d/oracle <br />/etc/rc.d/rc0.d/K05oracle <br />/etc/rc.d/rc1.d/K05oracle <br />/etc/rc.d/rc2.d/S80oracle <br />/etc/rc.d/rc3.d/S80oracle <br />/etc/rc.d/rc4.d/S80oracle <br />/etc/rc.d/rc5.d/S80oracle <br />/etc/rc.d/rc6.d/K05oracle <br /></pre></blockquote><p>
正如需要的那样，kill 连接的名字包含优先权 05 而 start 连接包含 80。如果你需要调整优先
权，(如：我们停止的优先权需要设为 03)，简单的调整 oracle init 脚本的chkconfig 
注释行并运行 reset命令 command，如下所示。符号连接会被改名： </p><blockquote><pre>[root]# chkconfig oracle reset <br />[root]# find /etc/rc.d -name '*oracle' -print <br />/etc/rc.d/init.d/oracle <br />/etc/rc.d/rc0.d/K03oracle <br />/etc/rc.d/rc1.d/K03oracle <br />/etc/rc.d/rc2.d/S80oracle <br />/etc/rc.d/rc3.d/S80oracle <br />/etc/rc.d/rc4.d/S80oracle <br />/etc/rc.d/rc5.d/S80oracle <br />/etc/rc.d/rc6.d/K03oracle <br /></pre></blockquote><h2>Red Hat 7中的改进</h2><p>
大家可能都知道了，inetd在 Red Hat 7中已经被<acronym title="Extended Internet Services Daemon">xinetd</acronym> 所取代(参考本站<a href="http://www.dbanotes.net/OpenSource/Using_xinetd.html"> "使用xinetd" </a>一文)。而且，chkconfig 
的功能已经被扩展，可以管理一些 <acronym title="Extended Internet Services Daemon">xinetd</acronym> 的 Internet 服务。例子如下： 
</p><blockquote><pre>[root]# chkconfig --list <br />... <br />xinetd based services: <br />finger: on <br />linuxconf-web: off <br />rexec: off <br />rlogin: off <br />rsh: off <br />ntalk: off <br />talk: off <br />telnet: on <br />tftp: off <br />wu-ftpd: on <br /></pre></blockquote><p>
禁掉一个 <acronym title="Extended Internet Services Daemon">xinetd</acronym> 服务，可能是 finger，你应该输入：
</p><blockquote><pre>[root]# chkconfig finger off. <br /></pre></blockquote><p>
很简捷啊，呵呵。可是，这里有个问题。当配置已经改变，命令 /etc/init.d/xinetd 
reload 指明 <acronym title="Extended Internet Services Daemon">xinetd</acronym> 自动重载入新的配置，被 
chkconfig 执行。这个脚本运行一个带有 SIGUSR2 信号的 kill 指示 <acronym title="Extended Internet Services Daemon">xinetd</acronym> 
进行一个“硬“重配置。 
</p><p>
那意味着什么？哦，当我测试的时候，通过 <acronym title="Extended Internet Services Daemon">xinetd</acronym> 提供的活动服务(如 Telnet, FTP 等)立刻被中止。如果你能计划在最合适的时间启动/禁止你的系统上的服务，可能不是个
问题。作为一种替代方式，你可以调整你的 /etc/init.d/xinetd 脚本 ，这样 reload 
选项发送一个 SIGUSR1 信号。 这是个“软“重配置。这将重启动你的服务而不中断你现存的连接 。 
</p><p>
chkconfig 管理下，添加<acronym title="Extended Internet Services Daemon">xinetd</acronym>服务只要简单的添加<acronym title="Extended Internet Services Daemon">xinetd</acronym>服务文件到 
/etc/xinetd.d目录中。chkconfig会自动的“捡起“它并使其可用，通过chkconfig 
工具进行管理。简洁阿！ 
</p><h2>结论 </h2><p>
现在你已经应该认识到红帽子的 chkconfig 工具管理 init 脚本的好处了，虽然它的功能似乎
简单了些，但是它节省时间，这使其成为一个系统管理员适用的命令，值得记牢。 
</p><br /><h2>参考信息(译者提供)</h2><br /><p><a href="http://www.fastcoder.net/%7Ethumper/software/sysadmin/chkconfig/">chkconfig</a> -http://www.fastcoder.net/~thumper/software/sysadmin/chkconfig/ </p><p><a href="http://www.dbanotes.net/OpenSource/Using_xinetd.html">使用 xinetd</a> - http://www.dbanotes.net/OpenSource/Using_xinetd.html </p><br /><hr /><script type="text/javascript"><!--
	google_ad_client = "pub-2198040673582211";
	google_ad_width = 468;
	google_ad_height = 60;
	google_ad_format = "468x60_as";
	google_ad_channel ="0605826110";
	google_ad_type = "text";
	google_color_border = "336699";
	google_color_bg = "FFFFFF";
	google_color_link = "0000FF";
	google_color_url = "008000";
	google_color_text = "000000";
	//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><iframe name="google_ads_frame" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-2198040673582211&amp;dt=1148884509531&amp;lmt=1129588305&amp;format=468x60_as&amp;output=html&amp;channel=0605826110&amp;url=http%3A%2F%2Fwww.dbanotes.net%2FOpenSource%2FManaging_Initscripts_with_RedHat%27s_chkconfig_CN.htm&amp;color_bg=FFFFFF&amp;color_text=000000&amp;color_link=0000FF&amp;color_url=008000&amp;color_border=336699&amp;ad_type=text&amp;ref=http%3A%2F%2Fwww.google.cn%2Fsearch%3Fhl%3Dzh-CN%26q%3Dchkconfig%26btnG%3DGoogle%2B%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;cc=100&amp;u_h=768&amp;u_w=1024&amp;u_ah=740&amp;u_aw=1024&amp;u_cd=32&amp;u_tz=480&amp;u_his=1&amp;u_java=true&amp;u_nplug=13&amp;u_nmime=50" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" frameborder="0" height="60" scrolling="no" width="468"></iframe><hr /><h2>本文译者</h2>
Fenng，某美资公司DBA，业余时间混迹于各数据库相关的技术论坛且乐此不疲。
目前关注如何利用ORACLE数据库有效地构建企业应用。对Oracle tuning、troubleshooting有一点研究。<br />
个人技术站点:<a href="http://www.dbanotes.net/">http://www.dbanotes.net/</a> 。
可以通过电子邮件 dbanotes@gmail.com 联系到他。
<hr /><h2>原文出处</h2><a href="http://www.dbanotes.net/OpenSource/Managing_Initscripts_with_RedHat%27s_chkconfig_CN.htm">
		http://www.dbanotes.net/OpenSource/Managing_Initscripts_with_RedHat's_chkconfig_CN.htm</a><br /><br /><a href="http://www.dbanotes.net/OpenSource.htm">回上页</a>&lt;-|-&gt;<a href="http://www.dbanotes.net/">回首页</a><br /><hr />

All Articles (by Fenng) are licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/">Creative Commons 
License</a>.<br />
I would welcome any feedback. Please send questions, comments or corrections to dbanotes@gmail.com <br /><a href="http://validator.w3.org/check?uri=http://www.dbanotes.net/OpenSource/Managing_Initscripts_with_RedHat%27s_chkconfig_CN.htm">Valid XHTML 4.01</a> / <a href="http://jigsaw.w3.org/css-validator/validator?uri=http://www.dbanotes.net/OpenSource/Managing_Initscripts_with_RedHat%27s_chkconfig_CN.htm">Valid CSS</a><br /><img src ="http://www.cnitblog.com/schkui/aggbug/11184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-05-29 14:41 <a href="http://www.cnitblog.com/schkui/archive/2006/05/29/11184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单的 mysql的 摘要</title><link>http://www.cnitblog.com/schkui/archive/2006/05/24/10987.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Wed, 24 May 2006 03:11:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/05/24/10987.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/10987.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/05/24/10987.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/10987.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/10987.html</trackback:ping><description><![CDATA[
		<div>    打开一个DOS命令窗口，在MySQL中建立一个数据库，并添加一个用户:<br />   C:\mysql\bin&gt; mysql -uroot -p      // 登陆   mysql [-u username] [-h host] [-p[password]] [dbname] <br />   ******** (输入root密码,如果还没有设置，直接输入回车即可)<br />   mysql&gt; GRANT ALL ON db1.* TO <a href="mailto:user1@localhost"><font color="#004377">user1@localhost</font></a> IDENTIFIED BY '123';   <a><font color="#004377">//user@"%</font></a>"  可以在其它的机子登陆 本例是本机<br />   mysql&gt; CREATE DATABASE db1;<br />   mysql&gt; quit<br />   <br />   <br />   <br />   导入数据库的结构<br />   C:\mysql\bin&gt; mysql -uuser1 -Ddb1 -p &lt; [myicqd目录]\ttt.sql<br />   password: 123<br />   <br />   <br />   修改密码    <br />   格式：mysqladmin -u用户名 -p旧密码 password 新密码 </div>
		<div>
				<br />   启动 <br />　　 MySQL安装完成后启动文件mysql在/etc/init.d目录下，在需要启动时运行下面命令即可。 <br />　　 [root@test1 init.d]# /etc/init.d/mysql start </div>
		<div>　　停止 <br />　　 /usr/bin/mysqladmin -u root -p shutdown <br />    [root@test1 init.d]# /etc/init.d/mysql stop<br />    重新启动MySQL服务 <br />　　 [root@test1 init.d]# /etc/init.d/mysql　restart </div>
		<div>
				<br />   数据库的备份 <br />     mysqldump --add-drop-table --add-locks --lock-tables  $MYSQL_DBNAME -uroot -pcanada&gt; $BACKUP_FILE<br />   数据库还原<br />    mysql $MYSQL_DBNAME -uroot -pcanada&lt; $RESTORE_FILE<br />    <br />    </div>
		<div>     MySQL的常用操作 </div>
		<div>　　 注意：MySQL中每个命令后都要以分号；结尾。 </div>
		<div>　　 1、显示数据库 <br />　　 mysql&gt; show databases; <br />　　 +----------+ <br />　　 | Database | <br />　　 +----------+ <br />　　 | mysql　　| <br />　　 | test　　 | <br />　　 +----------+ <br />　　 2 rows in set (0.04 sec) <br />　　 Mysql刚安装完有两个数据库：mysql和test。mysql库非常重要，它里面有MySQL的系统信息，我们改密码和新增用户，实际上就是用这个库中的相关表进行操作。 </div>
		<div>　　 2、显示数据库中的表 <br />　　 mysql&gt; use mysql; （打开库，对每个库进行操作就要打开此库，类似于foxpro ） <br />　　 Database changed </div>
		<div>　　 mysql&gt; show tables; <br />　　 +-----------------+ <br />　　 | Tables_in_mysql | <br />　　 +-----------------+ <br />　　 | columns_priv　　| <br />　　 | db　　　　　　　| <br />　　 | func　　　　　　| <br />　　 | host　　　　　　| <br />　　 | tables_priv　　 | <br />　　 | user　　　　　　| <br />　　 +-----------------+ <br />　　 6 rows in set (0.01 sec) </div>
		<div>　　 3、显示数据表的结构： <br />　　 describe 表名; </div>
		<div>　　 4、显示表中的记录： <br />　　 select * from 表名; <br />　　 例如：显示mysql库中user表中的纪录。所有能对MySQL用户操作的用户都在此表中。 <br />　　 Select * from user; </div>
		<div>　　 5、建库： <br />　　 create database 库名; <br />　　 例如：创建一个名字位aaa的库 <br />　　 mysql&gt; create databases aaa; <br />6、建表： <br />　　 use 库名； <br />　　 create table 表名 (字段设定列表)； <br />　　 例如：在刚创建的aaa库中建立表name,表中有id(序号，自动增长)，xm（姓名）,xb（性别）,csny（出身年月）四个字段 <br />　　 use aaa; <br />　　 mysql&gt; create table name (id int(3) auto_increment not null primary key, xm char(8),xb char(2),csny date); <br />　　 可以用describe命令察看刚建立的表结构。 <br />　　 mysql&gt; describe name; </div>
		<div>　　 +-------+---------+------+-----+---------+----------------+ <br />　　 | Field | Type　　| Null | Key | Default | Extra　　　　　| <br />　　 +-------+---------+------+-----+---------+----------------+ <br />　　 | id　　| int(3)　|　　　| PRI | NULL　　| auto_increment | <br />　　 | xm　　| char(8) | YES　|　　 | NULL　　|　　　　　　　　| <br />　　 | xb　　| char(2) | YES　|　　 | NULL　　|　　　　　　　　| <br />　　 | csny　| date　　| YES　|　　 | NULL　　|　　　　　　　　| <br />　　 +-------+---------+------+-----+---------+----------------+ </div>
		<div>　　 7、增加记录 <br />　　 例如：增加几条相关纪录。 <br />　　 mysql&gt; insert into name values(\'\',\'张三\',\'男\',\'1971-10-01\'); <br />　　 mysql&gt; insert into name values(\'\',\'白云\',\'女\',\'1972-05-20\'); <br />　　 可用select命令来验证结果。 <br />　　 mysql&gt; select * from name; <br />　　 +----+------+------+------------+ <br />　　 | id | xm　 | xb　 | csny　　　 | <br />　　 +----+------+------+------------+ <br />　　 |　1 | 张三 | 男　 | 1971-10-01 | <br />　　 |　2 | 白云 | 女　 | 1972-05-20 | <br />　　 +----+------+------+------------+ </div>
		<div>　　 8、修改纪录 <br />　　 例如：将张三的出生年月改为1971-01-10 <br />　　 mysql&gt; update name set csny=\'1971-01-10\' where xm=\'张三\'; </div>
		<div>　　 9、删除纪录 <br />　　 例如：删除张三的纪录。 <br />　　 mysql&gt; delete from name where xm=\'张三\'; </div>
		<div>　　 10、删库和删表 <br />　　 drop database 库名; <br />　　 drop table 表名； <br /></div>
<img src ="http://www.cnitblog.com/schkui/aggbug/10987.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-05-24 11:11 <a href="http://www.cnitblog.com/schkui/archive/2006/05/24/10987.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CVS使用手册 </title><link>http://www.cnitblog.com/schkui/archive/2006/05/24/10986.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Wed, 24 May 2006 02:56:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/05/24/10986.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/10986.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/05/24/10986.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/10986.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/10986.html</trackback:ping><description><![CDATA[
		<blockquote class="sumblk">
				<strong>摘要</strong>
				<br />CVS是一个C/S系统，多个开发人员通过一个中心版本控制系统来记录文件版本，从而达到保证文件同步的目的。(2004-07-05 20:19:18)</blockquote>
		<hr width="98%" noshade="" size="4" />
		<strong>By <a href="mailto:lanf at linuxaid dot com dot cn">lanf</a></strong>, 出处：http://www.chedong.com/tech/cvs_card.html<br /><br /><span class="contentblk"><p>作者： 车东 Email: chedongATbigfoot.com/chedongATchedong.com</p><p><b>内容摘要：</b></p><p>CVS是一个C/S系统，多个开发人员通过一个中心版本控制系统来记录文件版本，从而达到保证文件同步的目的。工作模式如下： </p><pre>       CVS服务器（文件版本库）<br />     /     |       \<br />     （版 本 同 步）<br />   /       |         \<br />开发者1  开发者2   开发者3<br /></pre><p>作为一般开发人员挑选2,6看就可以了，CVS的管理员则更需要懂的更多一些，最后还简单介绍了一些Windows下的cvs客户端使用，CVS远程用户认证的选择及与BUG跟踪系统等开发环境的集成问题。</p><ol><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#init">CVS环境初始化</a>：CVS环境的搭建 管理员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#daily">CVS的日常使用</a>：日常开发中最常用的CVS命令， 开发人员 管理员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#branch">CVS的分支开发</a>：项目按照不同进度和目标并发进行 管理员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#ssh">CVS的用户认证</a>：通过SSH的远程用户认证，安全，简单 管理员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#cvsweb">CVSWEB</a>：CVS的WEB访问界面大大提高代码版本比较的效率 管理员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#tag">CVS TAG</a>：将$<span style="FONT-WEIGHT: bold">Id</span>$ 加入代码注释中，方便开发过程的跟踪开发人员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#vss">CVS vs VSS</a>: CVS和Virsual SourceSafe的比较 开发人员 管理员 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#wincvs">WinCVS:</a> 通过SSH认证的WinCVS认证设置 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#cvstrac">基于CVSTrac的小组开发环境搭建</a>：通过CVSTrac实现web界面的CVS用户管理,集成的BUG跟踪和WIKI交流 
</li><li><a href="http://blog.csdn.net/kendiv/articles/285508.aspx#auth">CVS中的用户权限管理</a>：基于系统用户的CVS权限管理和基于CVSROOT/passwd的虚拟用户管理<br /></li></ol><p>一个系统20%的功能往往能够满足80%的需求，CVS也不例外，以下是CVS最常用的功能，可能还不到它全部命令选项的20%，作为一般开发人员平时会用cvs update和cvs commit就够了，更多的需求在实际应用过程中自然会出现，不时回头看看相关文档经常有意外的收获。</p><p><br /></p><b><a name="init">CVS环境初始化</a></b> 环境设置：指定CVS库的路径CVSROOT 
<p>tcsh<br />setenv CVSROOT /path/to/cvsroot<br />bash<br />CVSROOT=/path/to/cvsroot ; export CVSROOT</p><p>后面还提到远程CVS服务器的设置：<br />CVSROOT=:ext:$USER@test.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH<br /><br />初始化：CVS版本库的初始化。<br />cvs init</p><p>一个项目的首次导入<br />cvs import -m "write some comments here" project_name vendor_tag release_tag<br />执行后：会将所有源文件及目录导入到/path/to/cvsroot/project_name目录下<br /><i>vender_tag: 开发商标记<br />release_tag: 版本发布标记</i></p><p>项目导出：将代码从CVS库里导出<br />cvs checkout project_name<br /><i>cvs 将创建project_name目录，并将最新版本的源代码导出到相应目录中。这个checkout和Virvual SourceSafe中的check out不是一个概念，相对于Virvual SourceSafe的check out是cvs update， check in是cvs commit。</i><br /><br /></p><b><a style="FONT-WEIGHT: normal" name="daily">CVS的日常使用</a><b></b></b><p></p><p><b>注意：第一次导出以后，就不是通过cvs checkout来同步文件了，而是要进入刚才cvs checkout project_name导出的project_name目录下进行具体文件的版本同步（添加，修改，删除）操作。</b></p><p><u>将文件同步到最新的版本<br /></u>cvs update<br /><i>不制定文件名，cvs将同步所有子目录下的文件，也可以制定某个文件名/目录进行同步<br /></i>cvs update file_name<br /><i>最好每天开始工作前或将自己的工作导入到CVS库里前都要做一次，并养成“先同步 后修改”的习惯，和Virvual SourceSafe不同，CVS里没有文件锁定的概念，所有的冲突是在commit之前解决，如果你修改过程中，有其他人修改并commit到了CVS 库中，CVS会通知你文件冲突，并自动将冲突部分用<br />&gt;&gt;&gt;&gt;&gt;&gt;<br />content on cvs server<br />&lt;&lt;&lt;&lt;&lt;&lt;<br />content in your file<br />&gt;&gt;&gt;&gt;&gt;&gt;<br />标记出来，由你确认冲突内容的取舍。<br />版本冲突一般是在多个人修改一个文件造成的，但这种项目管理上的问题不应该指望由CVS来解决。</i></p><p><u>确认修改写入到CVS库里</u><br />cvs commit -m "write some comments here" file_name</p><p><i>注意：CVS的很多动作都是通过cvs commit进行最后确认并修改的，最好每次只修改一个文件。在确认的前，还需要用户填写修改注释，以帮助其他开发人员了解修改的原因。如果不用写-m "comments"而直接确认`cvs commit file_name` 的话，cvs会自动调用系统缺省的文字编辑器(一般是vi)要求你写入注释。<br />注释的质量很重要：所以不仅必须要写，而且必须写一些比较有意义的内容：以方便其他开发人员能够很好的理解<br />不好的注释，很难让其他的开发人员快速的理解：比如： -m "bug fixed" 甚至 -m ""<br />好的注释，甚至可以用中文: -m "在用户注册过程中加入了Email地址校验"</i><br /><br />修改某个版本注释：每次只确认一个文件到CVS库里是一个很好的习惯，但难免有时候忘了指定文件名，把多个文件以同样注释commit到CVS库里了，以下命令可以允许你修改某个文件某个版本的注释：<br />cvs admin -m 1.3:"write some comments here" file_name<br /><br /><u>添加文件</u><br />创建好新文件后，比如：touch new_file<br />cvs add new_file<br /><i>注意：对于图片，Word文档等非纯文本的项目，需要使用cvs add -kb选项按2进制文件方式导入(k表示扩展选项，b表示binary)，否则有可能出现文件被破坏的情况<br />比如：<br />cvs add -kb new_file.gif<br />cvs add -kb readme.doc</i></p><p><i>如果关键词替换属性在首次导入时设置错了怎么办？<br /></i>cvs admin -kkv new_file.css <br /><i><br /></i><span style="TEXT-DECORATION: underline">然后确认修改并注释</span><br />cvs ci -m "write some comments here"</p><p><u>删除文件</u><br />将某个源文件物理删除后，比如：rm file_name<br />cvs rm file_name<br />然后确认修改并注释<br />cvs ci -m "write some comments here"<br />以上面前2步合并的方法为：<br />cvs rm -f file_name<br />cvs ci -m "why delete file"<br /><i>注意：很多cvs命令都有缩写形式：commit=&gt;ci; update=&gt;up; checkout=&gt;co/get; remove=&gt;rm;</i></p><p><u>添加目录</u><br />cvs add dir_name<br /><br /><u>查看修改历史</u><br />cvs log file_name<br />cvs history file_name<br /><br /><u>查看当前文件不同版本的区别</u><br />cvs diff -r1.3 -r1.5 file_name<br />查看当前文件（可能已经修改了）和库中相应文件的区别<br />cvs diff file_name<br />cvs的web界面提供了更方便的定位文件修改和比较版本区别的方法，具体安装设置请看后面的cvsweb使用</p><p><u>正确的通过CVS恢复旧版本的方法</u>：<br />如果用cvs update -r1.2 file.name<br />这个命令是给file.name加一个STICK TAG： "1.2" ，虽然你的本意只是想将它恢复到1.2版本<br />正确的恢复版本的方法是：cvs update -p -r1.2 file_name &gt;file_name<br />如果不小心已经加成STICK TAG的话：用cvs update -A 解决</p><p><u>移动文件/文件重命名</u><br />cvs里没有cvs move或cvs rename，因为这两个操作是可以由先cvs remove old_file_name，然后cvs add new_file_name实现的。</p><p><u>删除/移动目录</u><br />最方便的方法是让管理员直接移动，删除CVSROOT里相应目录（因为CVS一个项目下的子目录都是独立的，移动到$CVSROOT目录下都可以作为新的独立项目：好比一颗树，其实砍下任意一枝都能独立存活），对目录进行了修改后，要求其开发人员重新导出项目cvs checkout project_name 或者用cvs update -dP同步。</p><p><u>项目发布导出不带CVS目录的源文件</u><br />做开发的时候你可能注意到了，每个开发目录下，CVS都创建了一个CVS/目录。里面有文件用于记录当前目录和CVS库之间的对应信息。但项目发布的时候你一般不希望把文件目录还带着含有CVS信息的CVS目录吧，这个一次性的导出过程使用cvs export命令，不过export只能针对一个TAG或者日期导出，比如：<br />cvs export -r release1 project_name <br />cvs export -D 20021023 project_name<br />cvs export -D now project_name</p><b><a name="branch">CVS Branch：项目多分支同步开发</a></b> 确认版本里程碑：多个文件各自版本号不一样，项目到一定阶段，可以给所有文件统一指定一个阶段里程碑版本号，方便以后按照这个阶段里程碑版本号导出项目，同时也是项目的多个分支开发的基础。<br /><p>cvs tag release_1_0</p><p><u>开始一个新的里程碑</u>：<br />cvs commit -r 2 标记所有文件开始进入2.x的开发</p><p><i>注意：CVS里的revsion和软件包的发布版本可以没有直接的关系。但所有文件使用和发布版本一致的版本号比较有助于维护。</i></p><p><u>版本分支的建立</u><br />在开发项目的2.x版本的时候发现1.x有问题，但2.x又不敢用，则从先前标记的里程碑：release_1_0导出一个分支 release_1_0_patch<br />cvs rtag -b -r release_1_0 release_1_0_patch proj_dir</p><p>一些人先在另外一个目录下导出release_1_0_patch这个分支：解决1.0中的紧急问题，<br />cvs checkout -r release_1_0_patch<br />而其他人员仍旧在项目的主干分支2.x上开发</p><p>在release_1_0_patch上修正错误后，标记一个1.0的错误修正版本号<br />cvs tag release_1_0_patch_1</p><p>如果2.0认为这些错误修改在2.0里也需要，也可以在2.0的开发目录下合并release_1_0_patch_1中的修改到当前代码中：<br />cvs update -j release_1_0_patch_1</p><b><a name="ssh">CVS的远程认证通过SSH远程访问CVS</a></b> 使用cvs本身基于pserver的远程认证很麻烦,需要定义服务器和用户组，用户名，设置密码等，<br /><p>常见的登陆格式如下：<br />cvs -d :pserver:cvs_user_name@cvs.server.address:/path/to/cvsroot login<br />例子：<br />cvs -d :pserver:cvs@samba.org:/cvsroot login</p><p>不是很安全，因此一般是作为匿名只读CVS访问的方式。从安全考虑，通过系统本地帐号认证并通过SSH传输是比较好的办法，通过在客户机的 /etc/profile里设置一下内容：<br />CVSROOT=:ext:$USER@cvs.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH<br />所有客户机所有本地用户都可以映射到CVS服务器相应同名帐号了。</p><p>比如:</p><p>CVS服务器是192.168.0.3，上面CVSROOT路径是/home/cvsroot，另外一台开发客户机是192.168.0.4，如果 tom在2台机器上都有同名的帐号，那么从192.168.0.4上设置了：<br />export CVSROOT=:ext:tom@192.168.0.3:/home/cvsroot<br />export CVS_RSH=ssh<br />tom就可以直接在192.168.0.4上对192.168.0.3的cvsroot进行访问了（如果有权限的话）<br />cvs checkout project_name<br />cd project_name<br />cvs update<br />...<br />cvs commit <br /></p><p>如果CVS所在服务器的SSH端口不在缺省的22，或者和客户端与CVS服务器端SSH缺省端口不一致，有时候设置了：<br />:ext:$USER@test.server.address#port:/path/to/cvsroot <br /><br />仍然不行，比如有以下错误信息：<br />ssh: test.server.address#port: Name or service not known<br />cvs [checkout aborted]: end of file from server (consult above messages if any)<br /><br />解决的方法是做一个脚本指定端口转向（不能使用alias，会出找不到文件错误）：<br />创建一个/usr/bin/ssh_cvs文件，假设远程服务器的SSH端口是非缺省端口：34567<br />#!/bin/sh<br />/usr/bin/ssh -p 34567 "$@"<br />然后：chmod +x /usr/bin/ssh_cvs<br />并CVS_RSH=ssh_cvs; export CVS_RSH</p><p>注意：port是指相应服务器SSH的端口，不是指cvs专用的pserver的端口<br /><br /></p><b><a name="cvsweb">CVSWEB：提高文件浏览效率</a></b> CVSWEB就是CVS的WEB界面，可以大大提高程序员定位修改的效率:<br /><p>使用的样例可以看：<a href="http://www.freebsd.org/cgi/cvsweb.cgi">http://www.freebsd.org/cgi/cvsweb.cgi</a></p><p>CVSWEB的下载：CVSWEB从最初的版本已经演化出很多功能界面更丰富的版本，这个是我个人感觉安装设置比较方便的：<br />原先在：<s>http://www.spaghetti-code.de/software/linux/cvsweb/</s>，但目前已经删除，<a href="http://www.linuxaid.com.cn/articles/1/0/cvsweb.tgz">目前仍可以在本站下载CVSWEB</a>，其实最近2年<a href="http://www.freebsd.org/projects/cvsweb.html">FreeBSD的CVSWeb项目</a>已经有了更好的发展吧，而当初没有用FreeBSD那个版本主要就是因为没有彩色的文件Diff功能。 <br />下载解包：<br />tar zxf cvsweb.tgz<br />把配置文件cvsweb.conf放到安全的地方（比如和apache的配置放在同一个目录下），<br />修改：cvsweb.cgi让CGI找到配置文件：<br />$config = $ENV{'CVSWEB_CONFIG'} || '/path/to/apache/conf/cvsweb.conf';<br /><br />转到/path/to/apache/conf下并修改cvsweb.conf：</p><ol><li>修改CVSROOT路径设置：<br />%CVSROOT = (<br />'Development' =&gt; '/path/to/cvsroot', #&lt;==修改指向本地的CVSROOT<br />); 
</li><li>缺省不显示已经删除的文档：<br />"hideattic" =&gt; "1",#&lt;==缺省不显示已经删除的文档 
</li><li>在配置文件cvsweb.conf中还可以定制页头的描述信息，你可以修改$long_intro成你需要的文字 </li></ol><p>CVSWEB可不能随便开放给所有用户，因此需要使用WEB用户认证：<br />先生成 passwd:<br />/path/to/apache/bin/htpasswd -c cvsweb.passwd user<br /><br />修改httpd.conf: 增加<br />&lt;Directory "/path/to/apache/cgi-bin/cvsweb/"&gt;<br />AuthName "CVS Authorization"<br />AuthType Basic<br />AuthUserFile /path/to/cvsweb.passwd<br />require valid-user<br />&lt;/Directory&gt;<br /><br /></p><b><a name="tag">CVS TAGS: $Id: cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $</a></b> 将$Id: cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $ 加在程序文件开头的注释里是一个很好的习惯，cvs能够自动解释更新其中的内容成：file_name version time user_name 的格式，比如：cvs_card.txt,v 1.1 2002/04/05 04:24:12 chedong Exp，可以这些信息了解文件的最后修改人和修改时间<br /><p><br /></p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#cccccc" border="1"><tbody><tr><td><pre><code>几个常用的缺省文件：<br />default.php<br />&lt;?php<br />/*<br /> * Copyright (c) 2002 Company Name.<br /> * $Header: /home/cvsroot/tech/cvs_card.html,<br /> * v 1.9 2003/11/09 07:57:11 chedong Exp $<br /> */<br /><br />?&gt;<br />====================================<br />Default.java: 注意文件头一般注释用 /* 开始 JAVADOC注释用 /** 开始的区别<br />/*<br /> * Copyright (c) 2002 MyCompany Name.<br /> * $Header: /home/cvsroot/tech/cvs_card.html,<br /> * v 1.9 2003/11/09 07:57:11 chedong Exp $<br /> */<br /><br />package com.mycompany;<br /><br />import java.;<br /><br />/**<br /> * comments here<br /> */<br />public class Default {<br />    /**<br />     * Comments here<br />     * @param<br />     * @return<br />     */<br />    public toString() {<br /><br />    }<br />}<br />====================================<br />default.pl:<br />#!/usr/bin/perl -w<br /># Copyright (c) 2002 Company Name.<br /># $Header: /home/cvsroot/tech/cvs_card.html,<br /> * v 1.9 2003/11/09 07:57:11 chedong Exp $<br /><br /># file comments here<br /><br />use strict;<br /><br /></code></pre></td></tr></tbody></table><b><a name="vss">CVS vs VSS</a></b><p>CVS没有文件锁定模式，VSS在check out同时，同时记录了文件被导出者锁定。 </p><p>CVS的update和commit， VSS是get_lastest_version和check in </p><p>对应VSS的check out/undo check out的CVS里是edit和unedit </p><p>在CVS中，标记自动更新功能缺省是打开的，这样也带来一个潜在的问题，就是不用-kb方式添加binary文件的话在cvs自动更新时可能会导致文件失效。</p><p>$Header: /home/cvsroot/tech/cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $ $Date: 2003/11/09 07:57:11 $这样的标记在Virsual SourceSafe中称之为Keyword Explaination，缺省是关闭的，需要通过OPITION打开，并指定需要进行源文件关键词扫描的文件类型：*.txt,*.java, *.html...</p><p>对于Virsual SourceSafe和CVS都通用的TAG有：<br />$Header: /home/cvsroot/tech/cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $<br />$Author: chedong $<br />$Date: 2003/11/09 07:57:11 $ <br />$Revision: 1.9 $ </p><p>我建议尽量使用通用的关键词保证代码在CVS和VSS都能方便的跟踪。 </p><b><a name="wincvs">WinCVS</a></b> 下载：<br /><p>cvs Windows客户端：目前稳定版本为1.2<br /><a href="http://cvsgui.sourceforge.net/">http://cvsgui.sourceforge.net</a><br />ssh Windows客户端<br /><a href="http://www.networksimplicity.com/openssh/">http://www.networksimplicity.com/openssh/</a><br /><br />安装好以上2个软件以后：<br />WinCVS客户端的admin==&gt;preference设置<br />1 在general选单里<br />设置CVSROOT： username@192.168.0.123:/home/cvsroot<br />设置Authorization: 选择SSH server<br /><br />2 Port选单里<br />钩上：check for alternate rsh name<br />并设置ssh.exe的路径，缺省是装在 C:\Program Files\NetworkSimplicity\ssh\ssh.exe </p><p>然后就可以使用WinCVS进行cvs操作了，所有操作都会跳出命令行窗口要求你输入服务器端的认证密码。 </p><p>当然，如果你觉得这样很烦的话，还有一个办法就是生成一个没有密码的公钥/私钥对，并设置CVS使用基于公钥/私钥的SSH认证（在general 选单里）。</p><p>可以选择的diff工具：examdiff<br />下载：<br /><a href="http://www.prestosoft.com/examdiff/examdiff.htm">http://www.prestosoft.com/examdiff/examdiff.htm</a><br />还是在WinCVS菜单admin==&gt;preference的WinCVS选单里<br />选上：Externel diff program<br />并设置diff工具的路径，比如：C:\Program Files\ed16i\ExamDiff.exe<br />在对文件进行版本diff时，第一次需要将窗口右下角的use externel diff选上。 </p><b><a name="cvstrac">基于CVSTrac的小组开发环境搭建</a></b> 作为一个小组级的开发环境，版本控制系统和BUG跟踪系统等都涉及到用户认证部分。如何方便的将这些系统集成起来是一个非常困难的事情，毕竟我们不能指望 Linux下有像Source Offsite那样集成度很高的版本控制/BUG跟踪集成系统。<br /><br />我个人是很反对使用pserver模式的远程用户认证的，但如果大部分组员使用WINDOWS客户端进行开发的话，总体来说使用 CVSROOT/passwd认证还是很难避免的，但CVS本身用户的管理比较麻烦。本来我打算自己用perl写一个管理界面的，直到我发现了 CVSTrac：一个基于WEB界面的BUG跟踪系统，它外挂在CVS系统上的BUG跟踪系统，其中就包括了WEB界面的CVSROOT/passwd文件的管理，甚至还集成了WIKIWIKI讨论组功能。 
<p>这里首先说一下CVS的pserver模式下的用户认证，CVS的用户认证服务是基于inetd中的：<br />cvspserver stream tcp nowait apache /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver<br />一般在2401端口（这个端口号很好记：49的平方）<br /><br />CVS用户数据库是基于CVSROOT/passwd文件，文件格式：<br />[username]:[crypt_password]:[mapping_system_user]<br />由于密码都用的是UNIX标准的CRYPT加密，这个passwd文件的格式基本上是apache的htpasswd格式的扩展（比APACHE的 PASSWD文件多一个系统用户映射字段），所以这个文件最简单的方法可以用<br />apache/bin/htpasswd -b myname mypassword <br />创建。注意：通过htpasswd创建出来的文件会没有映射系统用户的字段<br />例如：<br />new:geBvosup/zKl2<br />setup:aISQuNAAoY3qw<br />test:hwEpz/BX.rEDU </p><p>映射系统用户的目的在于：你可以创建一个专门的CVS服务帐号，比如用apache的运行用户apache，并将/home/cvsroot目录下的所有权限赋予这个用户，然后在passwd文件里创建不同的开发用户帐号，但开发用户帐号最后的文件读写权限都映射为apache用户，在SSH模式下多个系统开发用户需要在同一个组中才可以相互读写CVS库中的文件。</p><p>进一步的，你可以将用户分别映射到apache这个系统用户上。<br />new:geBvosup/zKl2:apache<br />setup:aISQuNAAoY3qw:apache<br />test:hwEpz/BX.rEDU:apache </p><p>CVSTrac很好的解决了CVSROOT/passwd的管理问题，而且包含了BUG跟踪报告系统和集成WIKIWIKI交流功能等，使用的 CGI方式的安装，并且基于<a href="http://www.gnu.org/copyleft/gpl.html">GNU Public License</a>：<br /></p><p align="left">在inetd里加入cvspserver服务：<br />cvspserver stream tcp nowait apache /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver</p><p align="left">xietd的配置文件：%cat cvspserver <br />service cvspserver<br />{<br />disable = no<br />socket_type = stream<br />wait = no<br />user = apache<br />server = /usr/bin/cvs<br />server_args = -f --allow-root=/home/cvsroot pserver<br />log_on_failure += USERID<br />}</p><p>注意：这里的用户设置成apache目的是和/home/cvsroot的所有用户一致，并且必须让这个这个用户对/home/cvsroot/下的 CVSROOT/passwd和cvstrac初始化生成的myproj.db有读取权限。</p><p></p><p>安装过程 </p><ol><li>下载：可以从<a href="http://www.cvstrac.org/">http://www.cvstrac.org</a> 下载<br />我用的是已经在Linux上编译好的应用程序包：cvstrac-1.1.2.bin.gz，<br />%gzip -d cvstrac-1.1.2.bin.gz<br />%chmod +x cvstrac-1.1.2.bin<br />#mv cvstarc-1.1.1.bin /usr/bin/cvstrac <br />如果是从源代码编译：<br />从 http://www.sqlite.org/download.html 下载SQLITE的rpm包：<br />rpm -i sqlite-devel-2.8.6-1.i386.rpm<br />从 ftp://ftp.cvstrac.org/cvstrac/ 下载软件包<br />解包，假设解包到/home/chedong/cvstrac-1.1.2下，并规划将cvstrac安装到/usr/local/bin目录下， cd /home/chedong/cvstrac-1.1.2 编辑linux-gcc.mk:<br />修改：<br />SRCDIR = /home/chedong/cvstrac-1.1.2<br />INSTALLDIR = /usr/local/bin<br />然后<br />mv linux-gcc.mk Makefile<br />make<br />#make install<br /><br /></li><li>初始化cvstrac数据库：假设数据库名是 myproj<br />在已经装好的CVS服务器上（CVS库这时候应该已经是初始化好了，比如：cvs init初始化在/home/cvsroot里），运行一下<br />%cvstrac init /home/cvsroot myproj<br />运行后，/home/cvsroot里会有一个的myproj.db库，使用CVSTRAC服务，/home/cvsroot/myproj.db /home/cvsroot/CVSROOT/readers /home/cvsroot/CVSROOT/writers /home/cvsroot/CVSROOT/passwd这几个文件对于web服务的运行用户应该是可写的，在RedHat8上，缺省就有一个叫 apache用户和一个apache组，所以在httpd.conf文件中设置了用apache用户运行web服务：<br />User apache<br />Group apache，<br />然后设置属于apache用户和apache组<br />#chown -R apache:apache /home/cvsroot<br />-rw-r--r-- 1 apache apache 55296 Jan 5 19:40 myproj.db<br />drwxrwxr-x 3 apache apache 4096 Oct 24 13:04 CVSROOT/<br />drwxrwxr-x 2 apache apache 4096 Aug 30 19:47 some_proj/<br />此外还在/home/cvsroot/CVSROOT中设置了：<br />chmod 664 readers writers passwd<br /></li><li>在apche/cgi-bin目录中创建脚本cvstrac:<br />#!/bin/sh<br />/usr/bin/cvstrac cgi /home/cvsroot<br />设置脚本可执行：<br />chmod +x /home/apache/cgi-bin/cvstrac<br /></li><li>从 http://cvs.server.address/cgi-bin/cvstrac/myproj 进入管理界面<br />缺省登录名：setup 密码 setup<br />对于一般用户可以从：<br />http://cvs.server.address/cgi-bin/cvstrac/myproj 
</li><li>在setup中重新设置了CVSROOT的路径后，/home/cvsroot<br />如果是初次使用需要在/home/cvsroot/CVSROOT下创建passwd, readers, writers文件<br />touch passwd readers writers<br />然后设置属于apache用户，<br />chown apache.apache passwd readers writers<br />这样使用setup用户创建新用户后会同步更新CVSROOT/passwd下的帐号<br /></li></ol><p align="left">修改登录密码，进行BUG报告等，<br />更多使用细节可以在使用中慢慢了解。<br /></p><p align="left">对于前面提到的WinCVS在perference里设置：<br />CVSROOT栏输入：username@ip.address.of.cvs:/home/cvsroot<br />Authenitication选择：use passwd file on server side <br />就可以了从服务器上进行CVS操作了。<br /></p><b><a name="auth">CVS的用户权限管理</a></b><p align="left">CVS的权限管理分2种策略：<br /></p><ul><li>基于系统文件权限的系统用户管理：适合多个在Linux上使用系统帐号的开发人员进行开发。 
</li><li>基于CVSROOT/passwd的虚拟用户管理：适合多个在Windows平台上的开发人员将帐号映射成系统帐号使用。 </li></ul>为什么使用apache/apache用户？首先RedHat8中缺省就有了，而且使用这个用户可以方便通过cvstrac进行WEB管理。<br />chown -R apache.apache /home/cvsroot<br />chmod 775 /home/cvsroot<br /><p align="left">Linux上通过ssh连接CVS服务器的多个开发人员：通过都属于apache组实现文件的共享读写<br />开发人员有开发服务器上的系统帐号：sysuser1 sysuser2，设置让他们都属于apache组，因为通过cvs新导入的项目都是对组开放的：664权限的，这样无论那个系统用户导入的项目文件，只要文件的组宿主是apache，所有其他同组系统开发用户就都可以读写；基于ssh远程认证的也是一样。<br /></p><p align="left">   apache(system group)<br />/            |           \<br />sysuser1   sysuser2     sysuser3<br /></p><p align="left">Windows上通过cvspserver连接CVS服务器的多个开发人员：通过在passwd文件种映射成 apache用户实现文件的共享读写<br />他们的帐号通过CVSROOT/passwd和readers writers这几个文件管理；通过cvstrac设置所有虚拟用户都映射到apache用户上即可。<br /></p><p align="left">   apache(system user)<br />/            |            \<br />windev1     windev2      windev3             </p><p align="left"></p><p></p><p>利用cvs + (WinCVS/cvsweb/cvstrac)，构成了一个相对完善的跨平台工作组开发版本控制环境。</p><p>相关资源： </p><p>CVS HOME：<br /><a href="http://www.cvshome.org/">http://www.cvshome.org</a></p><p>CVS FAQ：<br /><a href="http://www.loria.fr/%7Emolli/cvs-index.html">http://www.loria.fr/~molli/cvs-index.html</a><br /><br />相关网站:<br /><a href="http://directory.google.com/Top/Computers/Software/Configuration_Management/Tools/Concurrent_Versions_System/">http://directory.google.com/Top/Computers/Software/ Configuration_Management/Tools/Concurrent_Versions_System/</a><br /></p><p>CVS--并行版本系统<br /><a href="http://www.soforge.com/cvsdoc/zh_CN/book1.html">http://www.soforge.com/cvsdoc/zh_CN/book1.html</a></p><p>CVS 免费书:<br /><a href="http://cvsbook.red-bean.com/">http://cvsbook.red-bean.com/</a></p><p>CVS 命令的速查卡片：<br /><a href="http://www.refcards.com/about/cvs.html">http://www.refcards.com/about/cvs.html</a></p><p>WinCVS:<br /><a href="http://cvsgui.sourceforge.net/">http://cvsgui.sourceforge.net/</a></p><p>CVSTrac: A Web-Based Bug And Patch-Set Tracking System For CVS<br /><a href="http://www.cvstrac.org/">http://www.cvstrac.org</a></p><p>StatCVS：基于CVS的代码统计工具：按代码量，按开发者的统计表等<br /><a href="http://sourceforge.net/projects/statcvs">http://sourceforge.net/projects/statcvs<br /></a></p>如何在WEB开发中规划CVS上：在Google上查 "cvs web development"<br /><a href="http://ccm.redhat.com/bboard-archive/cvs_for_web_development/index.html">http://ccm.redhat.com/bboard-archive/cvs_for_web_development/index.html</a><br /><br />一些集成了CVS的IDE环境： <br /><a href="http://www.eclipse.org/">Eclipse</a><br /><a href="http://www.magicunix.com/product_ch.html">Magic C++</a><br /></span><img src ="http://www.cnitblog.com/schkui/aggbug/10986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-05-24 10:56 <a href="http://www.cnitblog.com/schkui/archive/2006/05/24/10986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载：Grep学习笔记</title><link>http://www.cnitblog.com/schkui/archive/2006/05/23/10957.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Tue, 23 May 2006 09:31:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/05/23/10957.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/10957.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/05/23/10957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/10957.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/10957.html</trackback:ping><description><![CDATA[
		<div class="titlepage">
				<div>
						<div>
								<div class="author">
										<h3 class="author">
												<span class="firstname">整理：Jims of <a href="http://www.ringkee.com/" target="_top">肥肥世家</a></span>
										</h3>
										<div class="affiliation">
												<div class="address">
														<p>
																<br />
																<tt class="email">&lt;<a href="mailto:yjnet@21cn.com">yjnet@21cn.com</a>&gt;</tt>
																<br />
														</p>
												</div>
										</div>
								</div>
						</div>
						<div>
								<p class="copyright">Copyright © 2004 本文遵从GPL协议，欢迎转载、修改、散布。</p>
						</div>
						<div>
								<p class="pubdate">第一次发布时间：2004年7月16日</p>
						</div>
				</div>
				<div>
				</div>
				<hr />
		</div>
		<div class="toc">
				<p>
						<b>Table of Contents</b>
				</p>
				<dl>
						<dt>
								<span class="sect1">
										<a href="http://man.chinaunix.net/newsoft/grep/open.htm#id2874797">1. grep简介</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://man.chinaunix.net/newsoft/grep/open.htm#id2875155">2. grep正则表达式元字符集（基本集）</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://man.chinaunix.net/newsoft/grep/open.htm#id2810113">3. 用于egrep和 grep -E的元字符扩展集</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://man.chinaunix.net/newsoft/grep/open.htm#id2810216">4. POSIX字符类</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://man.chinaunix.net/newsoft/grep/open.htm#id2810431">5. Grep命令选项</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://man.chinaunix.net/newsoft/grep/open.htm#id2861488">6. 实例</a>
								</span>
						</dt>
				</dl>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2874797">
												</a>1. grep简介</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>grep （global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来）是一种强大的文本搜索工具，它能使用正则表达式搜索文本，并把匹配的行打印出来。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展，支持更多的re元字符， fgrep就是fixed grep或fast grep，它们把所有的字母都看作单词，也就是说，正则表达式中的元字符表示回其自身的字面意义，不再特殊。linux使用GNU版本的grep。它功能更强，可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。</p>
				<p>grep的工作方式是这样的，它在一个或多个文件中搜索字符串模板。如果模板包括空格，则必须被引用，模板后的所有字符串被看作文件名。搜索的结果被送到屏幕，不影响原文件内容。</p>
				<p>grep可用于shell脚本，因为grep通过返回一个状态值来说明搜索的状态，如果模板搜索成功，则返回0，如果搜索不成功，则返回1，如果搜索的文件不存在，则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。</p>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2875155">
												</a>2. grep正则表达式元字符集（基本集）</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">^</span>
								</dt>
								<dd>
										<p>锚定行的开始 如：'^grep'匹配所有以grep开头的行。 </p>
								</dd>
								<dt>
										<span class="term">$</span>
								</dt>
								<dd>
										<p>锚定行的结束 如：'grep$'匹配所有以grep结尾的行。 </p>
								</dd>
								<dt>
										<span class="term">.</span>
								</dt>
								<dd>
										<p>匹配一个非换行符的字符 如：'gr.p'匹配gr后接一个任意字符，然后是p。 </p>
								</dd>
								<dt>
										<span class="term">*</span>
								</dt>
								<dd>
										<p>匹配零个或多个先前字符 如：'*grep'匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。</p>
								</dd>
								<dt>
										<span class="term">[]</span>
								</dt>
								<dd>
										<p>匹配一个指定范围内的字符，如'[Gg]rep'匹配Grep和grep。 </p>
								</dd>
								<dt>
										<span class="term">[^]</span>
								</dt>
								<dd>
										<p>匹配一个不在指定范围内的字符，如：'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头，紧跟rep的行。 </p>
								</dd>
								<dt>
										<span class="term">\(..\)</span>
								</dt>
								<dd>
										<p>标记匹配字符，如'\(love\)'，love被标记为1。 </p>
								</dd>
								<dt>
										<span class="term">\&lt;</span>
								</dt>
								<dd>
										<p>锚定单词的开始，如:'\&lt;grep'匹配包含以grep开头的单词的行。 </p>
								</dd>
								<dt>
										<span class="term">\&gt;</span>
								</dt>
								<dd>
										<p>锚定单词的结束，如'grep\&gt;'匹配包含以grep结尾的单词的行。 </p>
								</dd>
								<dt>
										<span class="term">x\{m\}</span>
								</dt>
								<dd>
										<p>重复字符x，m次，如：'0\{5\}'匹配包含5个o的行。 </p>
								</dd>
								<dt>
										<span class="term">x\{m,\}</span>
								</dt>
								<dd>
										<p>重复字符x,至少m次，如：'o\{5,\}'匹配至少有5个o的行。 </p>
								</dd>
								<dt>
										<span class="term">x\{m,n\}</span>
								</dt>
								<dd>
										<p>重复字符x，至少m次，不多于n次，如：'o\{5,10\}'匹配5--10个o的行。</p>
								</dd>
								<dt>
										<span class="term">\w</span>
								</dt>
								<dd>
										<p>匹配文字和数字字符，也就是[A-Za-z0-9]，如：'G\w*p'匹配以G后跟零个或多个文字或数字字符，然后是p。</p>
								</dd>
								<dt>
										<span class="term">\W</span>
								</dt>
								<dd>
										<p>\w的反置形式，匹配一个或多个非单词字符，如点号句号等。</p>
								</dd>
								<dt>
										<span class="term">\b</span>
								</dt>
								<dd>
										<p>单词锁定符，如: '\bgrepb\'只匹配grep。</p>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2810113">
												</a>3. 用于egrep和 grep -E的元字符扩展集</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">+</span>
								</dt>
								<dd>
										<p>匹配一个或多个先前的字符。如：'[a-z]+able'，匹配一个或多个小写字母后跟able的串，如loveable,enable,disable等。</p>
								</dd>
								<dt>
										<span class="term">?</span>
								</dt>
								<dd>
										<p>匹配零个或多个先前的字符。如：'gr?p'匹配gr后跟一个或没有字符，然后是p的行。</p>
								</dd>
								<dt>
										<span class="term">a|b|c</span>
								</dt>
								<dd>
										<p>匹配a或b或c。如：grep|sed匹配grep或sed</p>
								</dd>
								<dt>
										<span class="term">()</span>
								</dt>
								<dd>
										<p>分组符号，如：love(able|rs)ov+匹配loveable或lovers，匹配一个或多个ov。</p>
								</dd>
								<dt>
										<span class="term">x{m},x{m,},x{m,n}</span>
								</dt>
								<dd>
										<p>作用同x\{m\},x\{m,\},x\{m,n\}</p>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2810216">
												</a>4. POSIX字符类</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>为了在不同国家的字符编码中保持一至，POSIX(The Portable Operating System Interface)增加了特殊的字符类，如[:alnum:]是A-Za-z0-9的另一个写法。要把它们放到[]号内才能成为正则表达式，如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外，都支持POSIX的字符类。</p>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">[:alnum:]</span>
								</dt>
								<dd>
										<p>文字数字字符</p>
								</dd>
								<dt>
										<span class="term">[:alpha:]</span>
								</dt>
								<dd>
										<p>文字字符</p>
								</dd>
								<dt>
										<span class="term">[:digit:]</span>
								</dt>
								<dd>
										<p>数字字符</p>
								</dd>
								<dt>
										<span class="term">[:graph:]</span>
								</dt>
								<dd>
										<p>非空字符（非空格、控制字符）</p>
								</dd>
								<dt>
										<span class="term">[:lower:]</span>
								</dt>
								<dd>
										<p>小写字符</p>
								</dd>
								<dt>
										<span class="term">[:cntrl:]</span>
								</dt>
								<dd>
										<p>控制字符</p>
								</dd>
								<dt>
										<span class="term">[:print:]</span>
								</dt>
								<dd>
										<p>非空字符（包括空格）</p>
								</dd>
								<dt>
										<span class="term">[:punct:]</span>
								</dt>
								<dd>
										<p>标点符号</p>
								</dd>
								<dt>
										<span class="term">[:space:]</span>
								</dt>
								<dd>
										<p>所有空白字符（新行，空格，制表符）</p>
								</dd>
								<dt>
										<span class="term">[:upper:]</span>
								</dt>
								<dd>
										<p>大写字符</p>
								</dd>
								<dt>
										<span class="term">[:xdigit:]</span>
								</dt>
								<dd>
										<p>十六进制数字（0-9，a-f，A-F）</p>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2810431">
												</a>5. Grep命令选项</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">-?</span>
								</dt>
								<dd>
										<p>同时显示匹配行上下的？行，如：grep -2 pattern filename同时显示匹配行的上下2行。</p>
								</dd>
								<dt>
										<span class="term">-b，--byte-offset</span>
								</dt>
								<dd>
										<p>打印匹配行前面打印该行所在的块号码。</p>
								</dd>
								<dt>
										<span class="term">-c,--count</span>
								</dt>
								<dd>
										<p>只打印匹配的行数，不显示匹配的内容。</p>
								</dd>
								<dt>
										<span class="term">-f File，--file=File</span>
								</dt>
								<dd>
										<p>从文件中提取模板。空文件中包含0个模板，所以什么都不匹配。</p>
								</dd>
								<dt>
										<span class="term">-h，--no-filename</span>
								</dt>
								<dd>
										<p>当搜索多个文件时，不显示匹配文件名前缀。</p>
								</dd>
								<dt>
										<span class="term">-i，--ignore-case</span>
								</dt>
								<dd>
										<p>忽略大小写差别。</p>
								</dd>
								<dt>
										<span class="term">-q，--quiet</span>
								</dt>
								<dd>
										<p>取消显示，只返回退出状态。0则表示找到了匹配的行。</p>
								</dd>
								<dt>
										<span class="term">-l，--files-with-matches</span>
								</dt>
								<dd>
										<p>打印匹配模板的文件清单。</p>
								</dd>
								<dt>
										<span class="term">-L，--files-without-match</span>
								</dt>
								<dd>
										<p>打印不匹配模板的文件清单。</p>
								</dd>
								<dt>
										<span class="term">-n，--line-number</span>
								</dt>
								<dd>
										<p>在匹配的行前面打印行号。</p>
								</dd>
								<dt>
										<span class="term">-s，--silent</span>
								</dt>
								<dd>
										<p>不显示关于不存在或者无法读取文件的错误信息。</p>
								</dd>
								<dt>
										<span class="term">-v，--revert-match</span>
								</dt>
								<dd>
										<p>反检索，只显示不匹配的行。</p>
								</dd>
								<dt>
										<span class="term">-w，--word-regexp</span>
								</dt>
								<dd>
										<p>如果被\&lt;和\&gt;引用，就把表达式做为一个单词搜索。</p>
								</dd>
								<dt>
										<span class="term">-V，--version</span>
								</dt>
								<dd>
										<p>显示软件版本信息。</p>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2861488">
												</a>6. 实例</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>要用好grep这个工具，其实就是要写好正则表达式，所以这里不对grep的所有功能进行实例讲解，只列几个例子，讲解一个正则表达式的写法。</p>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">$ ls -l | grep '^a'</span>
								</dt>
								<dd>
										<p>通过管道过滤ls -l输出的内容，只显示以a开头的行。</p>
								</dd>
								<dt>
										<span class="term">$ grep 'test' d*</span>
								</dt>
								<dd>
										<p>显示所有以d开头的文件中包含test的行。</p>
								</dd>
								<dt>
										<span class="term">$ grep 'test' aa bb cc</span>
								</dt>
								<dd>
										<p>显示在aa，bb，cc文件中匹配test的行。</p>
								</dd>
								<dt>
										<span class="term">$ grep '[a-z]\{5\}' aa</span>
								</dt>
								<dd>
										<p>显示所有包含每个字符串至少有5个连续小写字符的字符串的行。</p>
								</dd>
								<dt>
										<span class="term">$ grep 'w\(es\)t.*\1' aa</span>
								</dt>
								<dd>
										<p>如果west被匹配，则es就被存储到内存中，并标记为1，然后搜索任意个字符（.*），这些字符后面紧跟着另外一个es（\1），找到就显示该行。如果用egrep或grep -E，就不用"\"号进行转义，直接写成'w(es)t.*\1'就可以了。</p>
								</dd>
						</dl>
				</div>
		</div>
<img src ="http://www.cnitblog.com/schkui/aggbug/10957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-05-23 17:31 <a href="http://www.cnitblog.com/schkui/archive/2006/05/23/10957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载 ：Awk学习笔记</title><link>http://www.cnitblog.com/schkui/archive/2006/05/23/10956.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Tue, 23 May 2006 09:29:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/05/23/10956.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/10956.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/05/23/10956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/10956.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/10956.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 整理：Jims of 肥肥世家																																																														&lt;jims.yang@gmail.com&gt;																																																																Copyrigh...&nbsp;&nbsp;<a href='http://www.cnitblog.com/schkui/archive/2006/05/23/10956.html'>阅读全文</a><img src ="http://www.cnitblog.com/schkui/aggbug/10956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-05-23 17:29 <a href="http://www.cnitblog.com/schkui/archive/2006/05/23/10956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载 ：Sed学习笔记</title><link>http://www.cnitblog.com/schkui/archive/2006/05/23/10955.html</link><dc:creator>爱易</dc:creator><author>爱易</author><pubDate>Tue, 23 May 2006 09:28:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/05/23/10955.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/10955.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/05/23/10955.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/10955.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/10955.html</trackback:ping><description><![CDATA[
		<div class="titlepage">
				<div>
						<div>
								<div class="author">
										<h3 class="author">
												<span class="firstname">作者：Jims of <a href="http://www.ringkee.com/" target="_top">肥肥世家</a></span>
										</h3>
										<div class="affiliation">
												<div class="address">
														<p>
																<tt class="email">&lt;<a href="mailto:jims.yang@gmail.com">jims.yang@gmail.com</a>&gt;</tt>
														</p>
												</div>
										</div>
								</div>
						</div>
						<div>
								<p class="copyright">Copyright © 2004，2005, 本文遵从GNU 的自由文档许可证(Free Document License)的条款，欢迎转载、修改、散布。</p>
						</div>
						<div>
								<p class="pubdate">发布时间:2004年09月20日</p>
						</div>
						<div>
								<p class="pubdate">最近更新:2005年12月22日，增加小技巧章节。</p>
						</div>
				</div>
				<div>
				</div>
				<hr />
		</div>
		<div class="toc">
				<p>
						<b>Table of Contents</b>
				</p>
				<dl>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2874786">1. Sed简介</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2875182">2. 定址</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2811706">3. Sed命令</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2810348">4. 选项</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2810450">5. 元字符集</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2861508">6. 实例</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2808415">7. 脚本</a>
								</span>
						</dt>
						<dt>
								<span class="sect1">
										<a href="http://www.ringkee.com/jims/technic_folder/linux/open?page=sed.htm#id2808439">8. 小技巧</a>
								</span>
						</dt>
				</dl>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2874786">
												</a>1. Sed简介</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>sed 是一种在线编辑器，它一次处理一行内容。处理时，把当前处理的行存储在临时缓冲区中，称为“模式空间”（pattern space），接着用sed命令处理缓冲区中的内容，处理完成后，把缓冲区的内容送往屏幕。接着处理下一行，这样不断重复，直到文件末尾。文件内容并没有改变，除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件；简化对文件的反复操作；编写转换程序等。以下介绍的是Gnu版本的Sed 3.02。</p>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2875182">
												</a>2. 定址</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>可以通过定址来定位你所希望编辑的行，该地址用数字构成，用逗号分隔的两个行数表示以这两行为起止的行的范围（包括行数表示的那两行）。如1，3表示1，2，3行，美元符号($)表示最后一行。范围可以通过数据，正则表达式或者二者结合的方式确定 。</p>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2811706">
												</a>3. Sed命令</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>调用sed命令有两种形式： </p>
				<div class="itemizedlist">
						<ul type="disc">
								<li>
										<p>sed [options] 'command' file(s)</p>
								</li>
								<li>
										<p>sed [options] -f scriptfile file(s)</p>
								</li>
						</ul>
				</div>
				<p>
				</p>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">a\</span>
								</dt>
								<dd>
										<p>在当前行后面加入一行文本。</p>
								</dd>
								<dt>
										<span class="term">b lable</span>
								</dt>
								<dd>
										<p>分支到脚本中带有标记的地方，如果分支不存在则分支到脚本的末尾。</p>
								</dd>
								<dt>
										<span class="term">c\</span>
								</dt>
								<dd>
										<p>用新的文本改变本行的文本。</p>
								</dd>
								<dt>
										<span class="term">d</span>
								</dt>
								<dd>
										<p>从模板块（Pattern space）位置删除行。</p>
								</dd>
								<dt>
										<span class="term">D</span>
								</dt>
								<dd>
										<p>删除模板块的第一行。</p>
								</dd>
								<dt>
										<span class="term">i\</span>
								</dt>
								<dd>
										<p>在当前行上面插入文本。</p>
								</dd>
								<dt>
										<span class="term">h</span>
								</dt>
								<dd>
										<p>拷贝模板块的内容到内存中的缓冲区。</p>
								</dd>
								<dt>
										<span class="term">H</span>
								</dt>
								<dd>
										<p>追加模板块的内容到内存中的缓冲区</p>
								</dd>
								<dt>
										<span class="term">g</span>
								</dt>
								<dd>
										<p>获得内存缓冲区的内容，并替代当前模板块中的文本。</p>
								</dd>
								<dt>
										<span class="term">G</span>
								</dt>
								<dd>
										<p>获得内存缓冲区的内容，并追加到当前模板块文本的后面。</p>
								</dd>
								<dt>
										<span class="term">l</span>
								</dt>
								<dd>
										<p>列表不能打印字符的清单。</p>
								</dd>
								<dt>
										<span class="term">n</span>
								</dt>
								<dd>
										<p>读取下一个输入行，用下一个命令处理新的行而不是用第一个命令。</p>
								</dd>
								<dt>
										<span class="term">N</span>
								</dt>
								<dd>
										<p>追加下一个输入行到模板块后面并在二者间嵌入一个新行，改变当前行号码。</p>
								</dd>
								<dt>
										<span class="term">p</span>
								</dt>
								<dd>
										<p>打印模板块的行。</p>
								</dd>
								<dt>
										<span class="term">P（大写）</span>
								</dt>
								<dd>
										<p>打印模板块的第一行。</p>
								</dd>
								<dt>
										<span class="term">q</span>
								</dt>
								<dd>
										<p>退出Sed。</p>
								</dd>
								<dt>
										<span class="term">r file</span>
								</dt>
								<dd>
										<p>从file中读行。</p>
								</dd>
								<dt>
										<span class="term">t label</span>
								</dt>
								<dd>
										<p>if分支，从最后一行开始，条件一旦满足或者T，t命令，将导致分支到带有标号的命令处，或者到脚本的末尾。</p>
								</dd>
								<dt>
										<span class="term">T label</span>
								</dt>
								<dd>
										<p>错误分支，从最后一行开始，一旦发生错误或者T，t命令，将导致分支到带有标号的命令处，或者到脚本的末尾。</p>
								</dd>
								<dt>
										<span class="term">w file</span>
								</dt>
								<dd>
										<p>写并追加模板块到file末尾。</p>
								</dd>
								<dt>
										<span class="term">W file</span>
								</dt>
								<dd>
										<p>写并追加模板块的第一行到file末尾。</p>
								</dd>
								<dt>
										<span class="term">!</span>
								</dt>
								<dd>
										<p>表示后面的命令对所有没有被选定的行发生作用。</p>
								</dd>
								<dt>
										<span class="term">s/re/string</span>
								</dt>
								<dd>
										<p>用string替换正则表达式re。</p>
								</dd>
								<dt>
										<span class="term">=</span>
								</dt>
								<dd>
										<p>打印当前行号码。</p>
								</dd>
								<dt>
										<span class="term">#</span>
								</dt>
								<dd>
										<p>把注释扩展到下一个换行符以前。</p>
								</dd>
								<dt>
										<span class="term">以下的是替换标记</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>g表示行内全面替换。</p>
														</li>
														<li>
																<p>p表示打印行。</p>
														</li>
														<li>
																<p>w表示把行写入一个文件。</p>
														</li>
														<li>
																<p>x表示互换模板块中的文本和缓冲区中的文本。</p>
														</li>
														<li>
																<p>y表示把一个字符翻译为另外的字符（但是不用于正则表达式）</p>
														</li>
												</ul>
										</div>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2810348">
												</a>4. 选项</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">-e command, </span>
										<span class="term">--expression=command</span>
								</dt>
								<dd>
										<p>允许多台编辑。</p>
								</dd>
								<dt>
										<span class="term">-h, --help</span>
								</dt>
								<dd>
										<p>打印帮助，并显示bug列表的地址。</p>
								</dd>
								<dt>
										<span class="term">-n, --quiet, --silent</span>
								</dt>
								<dd>
										<p>取消默认输出。</p>
								</dd>
								<dt>
										<span class="term">-f, --filer=script-file</span>
								</dt>
								<dd>
										<p>引导sed脚本文件名。</p>
								</dd>
								<dt>
										<span class="term">-V, --version</span>
								</dt>
								<dd>
										<p>打印版本和版权信息。</p>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2810450">
												</a>5. 元字符集</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">^</span>
								</dt>
								<dd>
										<p>锚定行的开始 如：/^sed/匹配所有以sed开头的行。 </p>
								</dd>
								<dt>
										<span class="term">$</span>
								</dt>
								<dd>
										<p>锚定行的结束 如：/sed$/匹配所有以sed结尾的行。 </p>
								</dd>
								<dt>
										<span class="term">.</span>
								</dt>
								<dd>
										<p>匹配一个非换行符的字符 如：/s.d/匹配s后接一个任意字符，然后是d。 </p>
								</dd>
								<dt>
										<span class="term">*</span>
								</dt>
								<dd>
										<p>匹配零或多个字符 如：/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。 </p>
								</dd>
								<dt>
										<span class="term">[]</span>
								</dt>
								<dd>
										<p>匹配一个指定范围内的字符，如/[Ss]ed/匹配sed和Sed。 </p>
								</dd>
								<dt>
										<span class="term">[^]</span>
								</dt>
								<dd>
										<p>匹配一个不在指定范围内的字符，如：/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头，紧跟ed的行。 </p>
								</dd>
								<dt>
										<span class="term">\(..\)</span>
								</dt>
								<dd>
										<p>保存匹配的字符，如s/\(love\)able/\1rs，loveable被替换成lovers。 </p>
								</dd>
								<dt>
										<span class="term">&amp;</span>
								</dt>
								<dd>
										<p>保存搜索字符用来替换其他字符，如s/love/**&amp;**/，love这成**love**。 </p>
								</dd>
								<dt>
										<span class="term">\&lt;</span>
								</dt>
								<dd>
										<p>锚定单词的开始，如:/\&lt;love/匹配包含以love开头的单词的行。 </p>
								</dd>
								<dt>
										<span class="term">\&gt;</span>
								</dt>
								<dd>
										<p>锚定单词的结束，如/love\&gt;/匹配包含以love结尾的单词的行。 </p>
								</dd>
								<dt>
										<span class="term">x\{m\}</span>
								</dt>
								<dd>
										<p>重复字符x，m次，如：/0\{5\}/匹配包含5个o的行。 </p>
								</dd>
								<dt>
										<span class="term">x\{m,\}</span>
								</dt>
								<dd>
										<p>重复字符x,至少m次，如：/o\{5,\}/匹配至少有5个o的行。 </p>
								</dd>
								<dt>
										<span class="term">x\{m,n\}</span>
								</dt>
								<dd>
										<p>重复字符x，至少m次，不多于n次，如：/o\{5,10\}/匹配5--10个o的行。</p>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2861508">
												</a>6. 实例</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="variablelist">
						<dl>
								<dt>
										<span class="term">删除：d命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed '2d' example-----删除example文件的第二行。</p>
														</li>
														<li>
																<p>$ sed '2,$d' example-----删除example文件的第二行到末尾所有行。</p>
														</li>
														<li>
																<p>$ sed '$d' example-----删除example文件的最后一行。</p>
														</li>
														<li>
																<p>$ sed '/test/'d example-----删除example文件所有包含test的行。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">替换：s命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记，则只有每行第一个匹配的test被替换成mytest。</p>
														</li>
														<li>
																<p>$ sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说，如果某一行开头的test被替换成mytest，就打印它。</p>
														</li>
														<li>
																<p>$ sed 's/^192.168.0.1/&amp;localhost/' example-----&amp;符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加 localhost，变成192.168.0.1localhost。</p>
														</li>
														<li>
																<p>$ sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1，所有loveable会被替换成lovers，而且替换的行会被打印出来。</p>
														</li>
														<li>
																<p>$ sed 's#10#100#g' example-----不论什么字符，紧跟着s命令的都被认为是新的分隔符，所以，“#”在这里是分隔符，代替了默认的“/”分隔符。表示把所有10替换成100。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">选定行的范围：逗号</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。</p>
														</li>
														<li>
																<p>$ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。</p>
														</li>
														<li>
																<p>$ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行，每行的末尾用字符串sed test替换。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">多点编辑：e命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示，第一条命令删除1至5行，第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令，那么第一个替换命令将影响第二个替换命令的结果。</p>
														</li>
														<li>
																<p>$ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">从文件读入：r命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed '/test/r file' example-----file里的内容被读进来，显示在与test匹配的行后面，如果匹配多行，则file的内容将显示在所有匹配行的下面。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">写入文件：w命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">追加命令：a命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed '/^test/a\\---&gt;this is a example' example&lt;-----'this is a example'被追加到以test开头的行后面，sed要求命令a后面有一个反斜杠。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">插入：i命令</span>
								</dt>
								<dd>
										<p>$ sed '/test/i\\</p>
										<p>new line</p>
										<p>-------------------------' example</p>
										<p>如果test被匹配，则把反斜杠后面的文本插入到匹配行的前面。</p>
								</dd>
								<dt>
										<span class="term">下一个：n命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配，则移动到匹配行的下一行，替换这一行的aa，变为bb，并打印该行，然后继续。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">变形：y命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写，注意，正则表达式元字符不能使用这个命令。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">退出：q命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed '10q' example-----打印完第10行后，退出sed。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">保持和获取：h命令和G命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed -e '/test/h' -e '$G example-----在sed处理文件的时候，每一行都被保存在一个叫模式空间的临时缓冲区中，除非行被删除或者输出被取消，否则所有被处理的行都将打印在屏幕上。接着模式空间被清空，并存入新的一行等待处理。在这个例子里，匹配test的行被找到后，将存入模式空间，h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是，当到达最后一行后，G命令取出保持缓冲区的行，然后把它放回模式空间中，且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说，任何包含test的行都被复制并追加到该文件的末尾。</p>
														</li>
												</ul>
										</div>
								</dd>
								<dt>
										<span class="term">保持和互换：h命令和x命令</span>
								</dt>
								<dd>
										<div class="itemizedlist">
												<ul type="disc">
														<li>
																<p>$ sed -e '/test/h' -e '/check/x' example -----互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。</p>
														</li>
												</ul>
										</div>
								</dd>
						</dl>
				</div>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2808415">
												</a>7. 脚本</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<p>Sed脚本是一个sed的命令清单，启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔，在命令的末尾不能有任何空白或文本，如果在一行中有多个命令，要用分号分隔。以#开头的行为注释行，且不能跨行。</p>
		</div>
		<div class="sect1" lang="en">
				<div class="titlepage">
						<div>
								<div>
										<h2 class="title" style="CLEAR: both">
												<a name="id2808439">
												</a>8. 小技巧</h2>
								</div>
						</div>
						<div>
						</div>
				</div>
				<div class="itemizedlist">
						<ul type="disc">
								<li>
										<p>在sed的命令行中引用shell变量时要使用双引号，而不是通常所用的单引号。下面是一个根据name变量的内容来删除named.conf文件中zone段的脚本：</p>
										<pre class="screen">name='zone\ "localhost"'
sed "/$name/,/};/d" named.conf 
</pre>
								</li>
						</ul>
				</div>
		</div>
<img src ="http://www.cnitblog.com/schkui/aggbug/10955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">爱易</a> 2006-05-23 17:28 <a href="http://www.cnitblog.com/schkui/archive/2006/05/23/10955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>