<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Live and Learn</title>
	<atom:link href="http://davidzhangzy.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://davidzhangzy.wordpress.com</link>
	<description>Still water run deep -- leading a quiet life</description>
	<lastBuildDate>Thu, 24 Dec 2009 15:35:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='davidzhangzy.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Live and Learn</title>
		<link>http://davidzhangzy.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://davidzhangzy.wordpress.com/osd.xml" title="Live and Learn" />
	<atom:link rel='hub' href='http://davidzhangzy.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Unix下自动化测试实践</title>
		<link>http://davidzhangzy.wordpress.com/2009/12/24/unix%e4%b8%8b%e8%87%aa%e5%8a%a8%e5%8c%96%e6%b5%8b%e8%af%95%e5%ae%9e%e8%b7%b5/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/12/24/unix%e4%b8%8b%e8%87%aa%e5%8a%a8%e5%8c%96%e6%b5%8b%e8%af%95%e5%ae%9e%e8%b7%b5/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 15:35:29 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[Software Testing]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=239</guid>
		<description><![CDATA[【前言】 网上看到很多关于用qtp、winrunner等工具来进行页面自动化测试的应用，但随着软件产业的发展，越来越多更大型的系统得到应用，随之变化的就是后台的变换，比如unix、linux、solaris、aix等。早期的很多系统都是基于windows server的应用和部署，qtp等工具很好的解决了自动化回归测试的问题，但对于unix平台下的测试，它就有点无能为力。而截止目前，还没有出现unix下的自动化回归测试工具，所以，我们工作中的自动化测试工具或脚本都是自己分析、设计、编码和测试，最终达到我们自己测试的需求，目的就是要提高在后台测试工作中的效率，让计算机帮我们完成大部分的手工劳动。笔者根据工作的过程和体会，把工作中unix平台下自动化测试应用的经验跟大家分享，希望能够起到抛砖引玉的效果。闲话少说，我们“挨踢”人喜欢直接，还是用例子来说明一下。 【举例1】 背景： 某应用系统T作为一个信息处理平台，要接收处理各种外部系统的电子单，而这种电子单是根据一定协议进行发送和接收、并处理返回的，但这种协议不是基于通用的TCP、UDP等协议，是各系统之间统一定制的特殊行业协议。而在这种电子单中，包含了各种各样的业务信息，系统会根据这些不同的信息进行不同的处理，得到的处理结果自然也是不同的。 应用系统T的前身是应用系统N，系统N所管理的外部系统比较分散，所用的协议与系统T也有差别，但有一个共同点就是，它们对于同样的业务信息所处理的结果应是一样，而且都会持久化保存数据库。下面的图是系统T的大概业务逻辑图： 1.jpg 下载 (23.37 KB) 2009-9-24 01:02 工作平台： OS：HP_UNIX DB：Sybase WebService：Tomcat Develop Language：Java 测试工作场景： 1、 按照不同业务制造大量电子单，然后发送到系统T的指定端口； 2、 发送电子单后，将系统T执行的结果与系统N的结果进行对比,检查系统T的结果是否执行正确； 测试困难分析： 1、 我们没有外部系统，如何模拟外部系统发送电子单？ 2、 系统T管理了7中业务类型，而每种业务类型大概有100种业务，如果全部覆盖，大概需要700多条测试数据，手工制作不太现实； 3、 大量的电子单的处理结果，难道都用肉眼比对？ 需求分析： 1、 编写模拟外部系统的发单客户端（基于socket协议）； 2、 使用系统N的海量电子单，然后按系统T的协议进行转换，用第一步的客户端发送（能保证覆盖所有业务）； 3、 编写程序，对系统N的处理结果和系统T的处理结果进行比对，然后打印出详细的对比结果，以供开发员定位错误问题所在； 工具实现步骤： 1、 由于开发平台都是java，为了跟系统T衔接的更好，我们选用java编写自动化测试工具。当然，测试工具编写人要对Java比较熟悉； 2、 对于需求1，我们需要知道如何进行socket数据的收发（网上资源大把，可以参考）； 3、 对于需求2，我们需要知道如何进行数据库的操作（JDBC资源网上也是大把）。数据库操作的目的，就是要从系统N的数据库中把旧的电子单取出来； 4、 对于需求3，在基于上面的第2和第3点上，当电子单发送后，系统T中会记录处理结果，然后就是要编写算法，对新旧结果进行比对； 5、 对于测试工具还应该实现可配置化，比如服务器IP、服务端口，旧数据库的IP、用户名、密码，新数据库的IP、用户名、密码，业务类型等，这就要求引入第三方的jar包，对xml文件进行解析； 部分代码： 下面部分代码说明： 此代码是java语言编写，IDE是Eclipse3.1； 下面是主体类（对比指令类）的一段主要代码，主要实现系统T和系统N的指令对比，并打印详细的对比日志。这其中可以看到有一个rx的变量，这是一个读取外部配置文件的对象，系统T和系统N的数据库连接信息、电子工单类型、对比条件等都是通过配置文件进行自定义的； 下面的代码用到的第三方jar包有jconn3.jar（sybase数据库连接）、dom4j-1.4.jar（读取配置文件）等； 1. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=239&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>【前言】</p>
<p>网上看到很多关于用qtp、winrunner等工具来进行页面自动化测试的应用，但随着软件产业的发展，越来越多更大型的系统得到应用，随之变化的就是后台的变换，比如unix、linux、solaris、aix等。早期的很多系统都是基于windows server的应用和部署，qtp等工具很好的解决了自动化回归测试的问题，但对于unix平台下的测试，它就有点无能为力。而截止目前，还没有出现unix下的自动化回归测试工具，所以，我们工作中的自动化测试工具或脚本都是自己分析、设计、编码和测试，最终达到我们自己测试的需求，目的就是要提高在后台测试工作中的效率，让计算机帮我们完成大部分的手工劳动。笔者根据工作的过程和体会，把工作中unix平台下自动化测试应用的经验跟大家分享，希望能够起到抛砖引玉的效果。闲话少说，我们“挨踢”人喜欢直接，还是用例子来说明一下。</p>
<p>【举例1】</p>
<p>背景：</p>
<p>某应用系统T作为一个信息处理平台，要接收处理各种外部系统的电子单，而这种电子单是根据一定协议进行发送和接收、并处理返回的，但这种协议不是基于通用的TCP、UDP等协议，是各系统之间统一定制的特殊行业协议。而在这种电子单中，包含了各种各样的业务信息，系统会根据这些不同的信息进行不同的处理，得到的处理结果自然也是不同的。<br />
应用系统T的前身是应用系统N，系统N所管理的外部系统比较分散，所用的协议与系统T也有差别，但有一个共同点就是，它们对于同样的业务信息所处理的结果应是一样，而且都会持久化保存数据库。下面的图是系统T的大概业务逻辑图：<br />
1.jpg<br />
下载 (23.37 KB)<br />
2009-9-24 01:02</p>
<p>工作平台：<br />
  OS：HP_UNIX<br />
  DB：Sybase<br />
  WebService：Tomcat<br />
  Develop Language：Java</p>
<p>        测试工作场景：<br />
        1、 按照不同业务制造大量电子单，然后发送到系统T的指定端口；<br />
        2、 发送电子单后，将系统T执行的结果与系统N的结果进行对比,检查系统T的结果是否执行正确；<br />
测试困难分析：<br />
        1、 我们没有外部系统，如何模拟外部系统发送电子单？<br />
        2、 系统T管理了7中业务类型，而每种业务类型大概有100种业务，如果全部覆盖，大概需要700多条测试数据，手工制作不太现实；<br />
        3、 大量的电子单的处理结果，难道都用肉眼比对？</p>
<p>需求分析：<br />
        1、  编写模拟外部系统的发单客户端（基于socket协议）；<br />
        2、 使用系统N的海量电子单，然后按系统T的协议进行转换，用第一步的客户端发送（能保证覆盖所有业务）；<br />
        3、 编写程序，对系统N的处理结果和系统T的处理结果进行比对，然后打印出详细的对比结果，以供开发员定位错误问题所在；</p>
<p>工具实现步骤：<br />
        1、 由于开发平台都是java，为了跟系统T衔接的更好，我们选用java编写自动化测试工具。当然，测试工具编写人要对Java比较熟悉；<br />
        2、 对于需求1，我们需要知道如何进行socket数据的收发（网上资源大把，可以参考）；<br />
        3、 对于需求2，我们需要知道如何进行数据库的操作（JDBC资源网上也是大把）。数据库操作的目的，就是要从系统N的数据库中把旧的电子单取出来；<br />
        4、 对于需求3，在基于上面的第2和第3点上，当电子单发送后，系统T中会记录处理结果，然后就是要编写算法，对新旧结果进行比对；<br />
        5、 对于测试工具还应该实现可配置化，比如服务器IP、服务端口，旧数据库的IP、用户名、密码，新数据库的IP、用户名、密码，业务类型等，这就要求引入第三方的jar包，对xml文件进行解析；<br />
部分代码：<br />
        下面部分代码说明：<br />
        此代码是java语言编写，IDE是Eclipse3.1；<br />
        下面是主体类（对比指令类）的一段主要代码，主要实现系统T和系统N的指令对比，并打印详细的对比日志。这其中可以看到有一个rx的变量，这是一个读取外部配置文件的对象，系统T和系统N的数据库连接信息、电子工单类型、对比条件等都是通过配置文件进行自定义的；<br />
        下面的代码用到的第三方jar包有jconn3.jar（sybase数据库连接）、dom4j-1.4.jar（读取配置文件）等；</p>
<p> <code>  1.   try{<br />
   2.                 FileWriter fw = new FileWriter("Instruct_err_order.txt");<br />
   3.                 FileWriter fw_log = new FileWriter("Contrast_log.txt");<br />
   4.                 FileWriter fw_true = new FileWriter("Contrast_true_order.txt");<br />
   5.                 PrintWriter out = new PrintWriter(fw);<br />
   6.                 PrintWriter out_log = new PrintWriter(fw_log);<br />
   7.                 PrintWriter out_true = new PrintWriter(fw_true);<br />
   8.</p>
<p>   9.                 out_log.println("Contrasting start time is:"+new Date());<br />
  10.                 out_log.println("------------------------------");<br />
  11.</p>
<p>  12.             //int<br />
  13. grp_id=Integer.valueOf(rx.getItem("/project/dbinfo","old_db_order_grp"+tabl<br />
  14. e_id));<br />
  15.                 String start_time=rx.getItem("/project/config","contrast_start_time");<br />
  16.                 String end_time=rx.getItem("/project/config","contrast_end_time");<br />
  17.</p>
<p>  18.               //2006.04.29修改，加入*****，然后把新加入的字段插入到临时表中，为<br />
  19.               //后面的统计做准备<br />
  20.                 String order_type=rx.getItem("/project/config","order_type");<br />
  21.                 //指令对比工单类型的判断<br />
  22.                 if(order_type.equals("all")){<br />
  23.                  str_Tips=" and 1=1 ";<br />
  24.                  out_log.println("Contrast workorder type is:all");<br />
  25.                 }else{<br />
  26.                  String[] tmp_order;<br />
  27.                  tmp_order=order_type.split(",");<br />
  28.                  str_Tips=" and (workorder_type_id='"+tmp_order[0]+"'";<br />
  29.                  out_log.print("Contrast workorder type is:"+tmp_order[0]);<br />
  30.                  for(int i=1;i='"+start_time+"' and<br />
  47. receive_time&lt;=&#039;&quot;+end_time+&quot;&#039;&quot;+str_Tips+&quot; &quot;+order_type+&quot; order by<br />
  48. workorder_no&quot;;<br />
  49.                 //System.out.println(sql_temp);<br />
  50.                 rs_temp=stmt_temp.executeQuery(sql_temp);<br />
  51.                 rs_temp.next();<br />
  52.                 int i=0;<br />
  53.                 String TempOrder=&quot;&quot;;<br />
  54.                 String oldOrder=&quot;&quot;;<br />
  55.                 while(!rs_temp.isAfterLast()){<br />
  56.                  //2006.04.29增加，为生产环境对比而增加<br />
  57.                 product_id_tmp=Integer.valueOf(rs_temp.getString(4).trim());<br />
  58.                 business_id_tmp=Integer.valueOf(rs_temp.getString(5).trim());<br />
  59.                 office_id_tmp=Integer.valueOf(rs_temp.getString(2).trim());<br />
  60. officegrp_id_tmp=Integer.valueOf(rs_temp.getString(3).trim());<br />
  61.                     date_tmp=rs_temp.getString(6).trim();<br />
  62.                 old_ordername=rx.getItem(&quot;/project/dbinfo&quot;,&quot;old_db_ordername&quot;);<br />
  63.    old_instrctname=rx.getItem(&quot;/project/dbinfo&quot;,&quot;old_db_instrctname&quot;);<br />
  64.                  TempOrder=rs_temp.getString(1).trim();<br />
  65.                  sql_old=&quot;select numListNo,szRecord from &quot;+old_ordername+&quot; where szRecordID=&#039;&quot;+TempOrder+&quot;&#039; and iLogID=-1 order by numListNo&quot;;<br />
  66.                  rs_old=stmt_old.executeQuery(sql_old);<br />
  67.                  rs_old.next();<br />
  68.                  if(rs_old.getRow()&lt;=0){<br />
  69.                   rs_temp.next();<br />
  70.                   continue;<br />
  71.                  }<br />
  72.               i=Integer.valueOf(rs_old.getString(1));<br />
  73.               oldOrder=rs_old.getString(2);<br />
  74.               sql_old=&quot;select szCmd,iCmdID,iChildCmdID from &quot;+old_instrctname+&quot; where numListNo=&quot;+i+&quot; order by iCmdID&quot;;<br />
  75.               rs_old=stmt_old.executeQuery(sql_old);<br />
  76.               rs_old.next();<br />
  77.               int old_rs_count=rs_old.getRow();<br />
  78.               if (old_rs_count&lt;=0){<br />
  79.                out_log.println(&quot;Old workorder unique No is:&quot;+i);<br />
  80.                out_log.println(&quot;Workorder No is:&quot;+TempOrder);<br />
  81.                out_log.println(&quot;Old workorder&#039;s instruct is empty,it can not contrast instructs!&quot;);<br />
  82.                out_log.println(&quot;------------------------------&quot;);<br />
  83.                rs_temp.next();<br />
  84.                CountOrder1=CountOrder1+1;<br />
  85.                continue;<br />
  86.               }<br />
  87. //              else{<br />
  88. //               sql_temp=&quot;select count(*) from &quot;+new_ordername+&quot; a where a.workorder_no=&#039;&quot;+rs_old.getString(&quot;szRecordID&quot;).toString().trim()+&quot;&#039;&quot;;<br />
  89. //               rs_temp=stmt_new.executeQuery(sql_temp);<br />
  90. //               rs_temp.next();<br />
  91. //               if(rs_temp.getRow()&lt;=0){<br />
  92. //                continue;<br />
  93. //               }<br />
  94. //              }<br />
  95.               out_log.println(&quot;Old workorder unique No is:&quot;+i);<br />
  96.               out_log.println(&quot;Workorder No is:&quot;+TempOrder);<br />
  97.</p>
<p>  98. //构建新工单查询sql语句，按照工单号查找<br />
  99.               sql_new=&quot;select instruct_id,childinstruct_id,instruct_text from &quot;+new_instrctname+&quot; where workorder_no=&#039;&quot;+TempOrder+&quot;&#039; order by instruct_id&quot;;<br />
 100.               rs_new=stmt_new.executeQuery(sql_new);<br />
 101.               rs_new.next();<br />
 102.               int new_rs_count=rs_new.getRow();<br />
 103.               if(new_rs_count&lt;=0){<br />
 104.                int insold_id=1;<br />
 105.                while(!rs_old.isAfterLast()){<br />
 106.                 out_log.println(&quot;The &quot;+insold_id+&quot;&#039;s instruct &#039;iCmdID&#039; is(old):&quot;+rs_old.getString(&quot;iCmdID&quot;).trim());<br />
 107.                 out_log.println(&quot;The &quot;+insold_id+&quot;&#039;s instruct &#039;iChildCmdID&#039; is(old):&quot;+rs_old.getString(&quot;iChildCmdID&quot;).trim());<br />
 108.                 out_log.println(&quot;The &quot;+insold_id+&quot;&#039;s instruct is(old):&quot;+rs_old.getString(&quot;szCmd&quot;).trim());<br />
 109.                 rs_old.next();<br />
 110.                 insold_id=insold_id+1;<br />
 111.                }<br />
 112.                out_log.println(Contrast_result1);<br />
 113.                out_log.println(&quot;------------------------------&quot;);<br />
 114.                out.println(&quot;Old workorder unique No is:&quot;+i);<br />
 115.                out.println(&quot;Workorder No is:&quot;+TempOrder);<br />
 116.                out.println(&quot;New workorder&#039;s content is:&quot;+woc.converse(oldOrder,&quot;1&quot;));<br />
 117.                   out.println(&quot;Old workorder&#039;s content is:&quot;+oldOrder);<br />
 118.                out.println(Contrast_result1);<br />
 119.                   out.println(&quot;------------------------------&quot;);<br />
 120.               }<br />
 121.               else{<br />
 122.                boolean isTrue=true;<br />
 123.                int ins_id=1;<br />
 124.                while(!rs_old.isAfterLast()){<br />
 125.                 out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct &#039;iCmdID&#039; is(old):&quot;+rs_old.getString(&quot;iCmdID&quot;).trim());<br />
 126.                 out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct &#039;iChildCmdID&#039; is(old):&quot;+rs_old.getString(&quot;iChildCmdID&quot;).trim());<br />
 127.                 out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct is(old):&quot;+rs_old.getString(&quot;szCmd&quot;).trim());<br />
 128.                 if(rs_new.isAfterLast()){<br />
 129.                  out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct is empty(new)!&quot;);<br />
 130.                  isTrue=false;<br />
 131.                  //继续输出旧指令<br />
 132.                  rs_old.next();<br />
 133.                  ins_id=ins_id+1;<br />
 134.                     while(!rs_old.isAfterLast()){<br />
 135.                      out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct &#039;iCmdID&#039; is(old):&quot;+rs_old.getString(&quot;iCmdID&quot;).trim());<br />
 136.                      out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct &#039;iChildCmdID&#039; is(old):&quot;+rs_old.getString(&quot;iChildCmdID&quot;).trim());<br />
 137.                      out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct is(old):&quot;+rs_old.getString(&quot;szCmd&quot;).trim());<br />
 138.                      rs_old.next();<br />
 139.                      ins_id=ins_id+1;<br />
 140.                     }<br />
 141.                  break;<br />
 142.                 }<br />
 143.                 else{<br />
 144.                  out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct &#039;instruct_id&#039; is(new):&quot;+rs_new.getString(&quot;instruct_id&quot;).trim());<br />
 145.                  out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct &#039;childinstruct_id&#039; is(new):&quot;+rs_new.getString(&quot;childinstruct_id&quot;).trim());<br />
 146.                  out_log.println(&quot;The &quot;+ins_id+&quot;&#039;s instruct is(new):&quot;+rs_new.getString(&quot;instruct_text&quot;).trim());<br />
 147.                  if(contrastType.equals(&quot;id&quot;)){<br />
 148.                   //指令对比方式<br />
 149.                   if (!rs_old.getString(&quot;iCmdID&quot;).trim().equals(rs_new.getString(&quot;instruct_id&quot;).trim()) || (!rs_old.getString(&quot;iChildCmdID&quot;).trim().equals(rs_new.getString(&quot;childinstruct_id&quot;).trim()))){<br />
 150.                   //if (!rs_old.getString(&quot;szCmd&quot;).trim().equals(rs_new.getString(&quot;instruct_text&quot;).trim())){<br />
 151.                    isTrue=false;<br />
 152.                    //break;<br />
 153.                   }<br />
 154.                  }else{<br />
 155.                   //内容对比方式<br />
 156.                   if (!rs_old.getString(&quot;szCmd&quot;).trim().equals(rs_new.getString(&quot;instruct_text&quot;).trim())){<br />
 157.                    isTrue=false;<br />
 158.                   }<br />
 159.                  }<br />
 160.                  ins_id=ins_id+1;<br />
 161.                  rs_old.next();<br />
 162.                  rs_new.next();<br />
 163.                 }<br />
 164.                }<br />
 165.                out_log.println(&quot;Instuct&#039;s contrasting result is:&quot;+isTrue);<br />
 166.                out_log.println(&quot;------------------------------&quot;);<br />
 167.                if(isTrue){<br />
 168.                 CouTrue=CouTrue+1;<br />
 169.                 out.println(&quot;------------------------------&quot;);<br />
 170.                 out_true.println(woc.converse(oldOrder,&quot;1&quot;));<br />
 171.                 //2006.04.29增加，为生产环境对比而增加<br />
 172.                 str_Tips=&quot;insert into t_Contrast_Instuct values&quot;+<br />
 173. &quot;(&#039;&quot;+TempOrder+&quot;&#039;,&quot;+office_id_tmp+&quot;,&quot;+officegrp_id_tmp+&quot;,&quot;+product_id_tmp+&quot;,&quot;+business_id_tmp+&quot;,1,convert(datetime,&#039;&quot;+date_tmp+&quot;&#039;))&quot;;<br />
 174.                 //System.out.println(str_Tips);<br />
 175.                 stmt_Tips.executeUpdate(str_Tips);<br />
 176.                }<br />
 177.                else{<br />
 178.                    out.println(&quot;Old workorder unique No is:&quot;+i);<br />
 179.                    out.println(&quot;Workorder No is:&quot;+TempOrder);<br />
 180.                 out.println(&quot;New workorder&#039;s content is:&quot;+woc.converse(oldOrder,&quot;1&quot;));<br />
 181.                 out.println(&quot;Old workorder&#039;s content is:&quot;+oldOrder);<br />
 182.                 out.println(Contrast_result2);<br />
 183.                 out.println(&quot;------------------------------&quot;);<br />
 184.                 //2006.04.29增加，为生产环境对比而增加<br />
 185.                 str_Tips=&quot;insert into t_Contrast_Instuct values&quot;+<br />
 186. &quot;(&#039;&quot;+TempOrder+&quot;&#039;,&quot;+office_id_tmp+&quot;,&quot;+officegrp_id_tmp+&quot;,&quot;+product_id_tmp+&quot;,&quot;+business_id_tmp+<br />
 187.                  &quot;,0,convert(datetime,&#039;&quot;+date_tmp+&quot;&#039;))&quot;;<br />
 188.                 stmt_Tips.executeUpdate(str_Tips);<br />
 189.                }<br />
 190.               }<br />
 191.               rs_temp.next();<br />
 192.               CountOrder2=CountOrder2+1;<br />
 193.              }<br />
 194.                 //-------------------------<br />
 195.                 DecimalFormat df = new DecimalFormat();<br />
 196.                 df.applyPattern(&quot;#.0000%&quot;);<br />
 197.                 //-------------------------<br />
 198.             out_log.println(&quot;The number which instruct&#039;s contrasting is ture is:&quot;+CouTrue);<br />
 199.              EndTime=new Date();<br />
 200.              out_log.println(&quot;Contrasting end time is:&quot;+EndTime);<br />
 201.              out_log.println(&quot;It has &quot;+CountOrder1+&quot; old workorder instructs is empty,so it can not contrast the instructs!&quot;);<br />
 202.              out_log.println(&quot;Have been contrasted &quot;+CountOrder2+&quot; workorders!&quot;);<br />
 203. out_log.println(&quot;-----------------------------------------------------------------&quot;);<br />
 204.              out_log.println(&quot;The right percent is :&quot;+df.format((double)CouTrue /(double)CountOrder2));<br />
 205.              out_log.println(&quot;----------------------&quot;);<br />
 206.              System.out.println(&quot;The number which instruct&#039;s contrasting is ture is:&quot;+CouTrue);<br />
 207.              System.out.println(&quot;Contrasting end time is:&quot;+EndTime);<br />
 208.              System.out.println(&quot;It has &quot;+CountOrder1+&quot; old workorder instructs is empty,so it can not contrast the instructs!&quot;);<br />
 209.              System.out.println(&quot;Have been contrasted &quot;+CountOrder2+&quot; workorders!&quot;);<br />
 210.              System.out.println(&quot;The right percent is :&quot;+df.format((double)CouTrue /(double)CountOrder2));<br />
 211.    }catch(java.io.IOException ex){<br />
 212.             System.out.println(&quot;File not found!&quot;);<br />
 213.         }<br />
</code><br />
复制代码<br />
【举例2】<br />
背景：<br />
        某系统M对外开放了3个基于SOAP协议的接口，而每个接口都提供了多达数十种的业务操作，而业务操作可能有先后依赖关系。</p>
<p>工作平台：<br />
  OS：Solaris 9.0<br />
  DB：Oracle<br />
  WebService：Weblogic 8.1<br />
  Develop Language：Java</p>
<p>测试工作场景：<br />
        构造不同业务的xml文件,比如开帐号（addUser.xml）,修改帐号信息(mdifyUser.xml)等，用xmlspy发送，然后验证返回信息是否<br />
正确；</p>
<p>测试困难分析：<br />
        1、然后用xmlspy工具一次发一条的方式来进行回归，需要大量的重复劳动；每次回归测试接口，都要制作达30个以上的xml文件，由于系统M的特殊性，工作环境不能直连，只能通过一台Linux服务器或者一台windows 2003server服务器中转，此windows服务器上安装有xmlspy，但windows服务器的远程连接license只有2个，经常抢不到连接，后果就是延误测试时间或者加班测试；</p>
<p>需求分析：<br />
        由于Linux服务器不受连接限制，我们可以通过Linux服务器来发送<br />
        xml文件给接口，不受windows的license限制；<br />
        2、 需要编写工具，能批量发送xml文件给接口服务；<br />
        3、 需要该工具能按定义顺序发送xml文件并检查返回结果是否正确，并打印出返回结果的关键字信息，供判断出错问题所在；<br />
        4、 对于该测试工具，更主要的是要能实现可配置，比如接口个数、文件发送顺序、参数化字段、主关键字值等；</p>
<p>工具实现步骤：<br />
        对于需求1，我们需要知道如何发送xml文件到接口服务端口（笔者开始在此事想用基于soap协议的jar来构建xml文件，后来由于需要回归的 xml文件太多，全部参数化不太现实，就改用文件发送方式。此处可以共享一下笔者借鉴的东西，大家可以到网上搜索SOAPClient4XG关键字）；<br />
        对于需求2，其实很简单，知道Java取文件夹和文件操作、循环操作即可；<br />
        对于需求3，也很简单，知道Java的文件流操作和BufferedReader类操作即可；<br />
        对于需求4，在上面例子1中的测试工具编写要求中的第5点已说明；<br />
部分代码：</p>
<p>  <code> 1. // 当resultNo的值不为0时，还需打印resultInfo信息，以供查问题<br />
   2.    int_start=str_inputLine.indexOf("ext:resultInfo");<br />
   3.    int_end=str_inputLine.indexOf("/ext:resultInfo");<br />
   4.    if(str_inputLine.indexOf("ext:resultInfo")&gt;=0){<br />
   5.     if(str_inputLine.indexOf("&gt;0&lt;&quot;)&lt;0){<br />
   6.      outlog.println(xml_file+&quot; : &quot;+str_inputLine.substring(int_start-1,int_end+16));<br />
   7.     }<br />
   8.    }<br />
   9.    outlog.println();<br />
  10.<br />
  11.         }catch(IOException ex){<br />
  12.          ex.printStackTrace();<br />
  13.          outlog.println(xml_file + &quot; : this file is failed!&quot;);<br />
  14.          outlog.println();<br />
  15.         }<br />
  16.     }<br />
  17.</p>
<p>  18.     // 同步拷贝文件流到字节输出流，并保证在拷贝过程中，这两个流不受其他线程影响<br />
  19.     public void copy(InputStream in, OutputStream out) throws IOException {<br />
  20.<br />
  21.      synchronized (in) {<br />
  22.        synchronized (out) {<br />
  23.          byte[] buffer = new byte[256];<br />
  24.          while (true) {<br />
  25.            int bytesRead = in.read(buffer);<br />
  26.            if (bytesRead == -1) break;<br />
  27.            out.write(buffer, 0, bytesRead);<br />
  28.          }<br />
  29.        }<br />
  30.      }<br />
  31.     }</code></p>
<p>复制代码<br />
【举例3】<br />
背景：<br />
        系统M有一后台服务，是该系统的最前端模块，它负责接收并处理基于国际通用的X协议包。而该系统将处理多达200多种的业务组合，接收不同的业务包，处理返回的结果就不同。但有一点需要注意，对于同一个包，在基础数据不变的情况下，系统对它的处理返回结果也是不变的。<br />
工作平台：<br />
  OS：Solaris 9.0<br />
  DB：Oracle<br />
  Develop Language：C++</p>
<p>测试工作场景：<br />
        构建不同业务包，用开源的客户端发送，然有用肉眼校验返回的结果是否正确；<br />
测试困难分析：<br />
        每次系统回归，都要对200多种业务进行发包回归测试，需要进行大量的手工劳动；<br />
        现有的业务还在增加，也就是说，手工回归的工作量会继续慢慢增大；<br />
需求分析：<br />
        1、 批量发送所有的业务包数据，并保存系统处理返回信息；<br />
        2、 可以用一次系统回归测试的正确结果做一个校验基准文件，以后每次回归，可以把当次测试的系统返回信息同基准文件进行比对；<br />
工具实现步骤：<br />
        1、 对于需求1，由于这是后台发包，而且有开源的客户端，我们在Solaris 9.0服务器上编译一个客户端，然后用shell编写脚本，循环发包即可，但得事先把测试数据准备齐全和正确；<br />
        2、 对于需求2，就是对shell脚本的要求了，主要用到了head、perl、diff等命令；<br />
        需要注意的是，这个脚本完成后，只需要对不断增加的业务测试数据进行维护即可；</p>
<p>部分代码：</p>
<p>   <code>1.   for i in $FILE_LIST<br />
   2. do<br />
   3.         while read LINE<br />
   4.          do<br />
   5.                 ACCOUNT=`echo $LINE | awk -F@ '{print $1}'`<br />
   6.                 FILE_NAME="$ACCOUNT"_"$i"<br />
   7.                 ./radtest $LINE &gt; $TEMP_DIR/$FILE_NAME<br />
   8.                 ID=`head -1 $TEMP_DIR/$FILE_NAME | awk '{printf $5}'`<br />
   9.                 IPPORT=`head -1 $TEMP_DIR/$FILE_NAME | awk '{printf $7}'`<br />
  10.                 #sed 's/'"$ID"'/999/g' $TEMP_DIR/$FILE_NAME &gt; $TEMP_DIR/$FILE_NAME.bak<br />
  11.                 #rm $TEMP_DIR/$FILE_NAME<br />
  12.                 #mv $TEMP_DIR/$FILE_NAME.bak $TEMP_DIR/$FILE_NAME<br />
  13.                 perl -pi -e 's/id '"$ID"'/id 999/g' $TEMP_DIR/$FILE_NAME<br />
  14.                 perl -pi -e 's/id='"$ID"'/id=999/g' $TEMP_DIR/$FILE_NAME<br />
  15.                 perl -pi -e 's/'"$IPPORT"'/'"$IP":"$PORT"'/g' $TEMP_DIR/$FILE_NAME<br />
  16.                 DIFF=`diff $TEMP_DIR/$FILE_NAME $TRUE_RESULT_DIR/$FILE_NAME | wc -w`<br />
  17.                 if [ $DIFF -gt 0 ]<br />
  18.                 then<br />
  19.                         printf "This account is error : $FILE_NAME\n" &gt;&gt; $RESULT<br />
  20.                         COUNT=$((COUNT+1))<br />
  21.                 fi<br />
  22.         done &lt; $DATA_DIR/$i<br />
  23.         LOOP=$((LOOP+1))<br />
  24.         printf &quot;\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bProcess: $LOOP / $SUM&quot;<br />
  25. done  </code></p>
<p>复制代码<br />
【总结】<br />
        当这些测试工具完成后，不言而喻，测试的工作就轻松、简单多了！而且，测试工具提供的详细的日志，给开发员的纠错提供了很好的帮助，大大的节省了开发和测试成本。<br />
        上面的3个例子，都是笔者在工作中实践总结出来的，这里主要讲的是测试工具或脚本的产生过程和思路，设计到的技术也无非是大家耳熟能详的Java、JDBC、Shell等，由于商业原因，笔者不方便把工具全部共享出来。下面我们来分析一下这些测试工具共同点和不同点。<br />
共同点：<br />
        测试工作很难开展（外部条件未达到）或者是测试工作量巨大（而且是大量的纯手工有规律的劳动）；<br />
        可以借助编程或者写shell脚本来实现自动化；<br />
        选择开发工具时，尽量跟后台开发语言一致；<br />
不同点：<br />
        当涉及到数据库、协议等时，得用编程来实现自动化。而对于后台已经有客户端、操作命令等时，可以用shell来实现自动化。当然，涉及的方面较多时，可能既得编程，又得写shell脚本；<br />
        不同的数据库、协议等，所使用的第三方jar是不同的。对于shell脚本也是一样，不同的平台，可能一些基本命令也不同，比如awk和nawk，等等；<br />
        当然，这里的例子在众多的测试情况中，是微不足道的，但是只要我们养成一种良好的思考习惯，注意积累，我想我们的测试工作可能会越来越轻松，越来越快乐！</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/239/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=239&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/12/24/unix%e4%b8%8b%e8%87%aa%e5%8a%a8%e5%8c%96%e6%b5%8b%e8%af%95%e5%ae%9e%e8%b7%b5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>Guide to Linux Find Command Mastery</title>
		<link>http://davidzhangzy.wordpress.com/2009/12/09/guide-to-linux-find-command-mastery/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/12/09/guide-to-linux-find-command-mastery/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 05:06:12 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/2009/12/09/guide-to-linux-find-command-mastery/</guid>
		<description><![CDATA[A quick introduction to the most powerful—as well as confusing—aspects of this ubiquitous command. Published July 2008 The Linux find command is simultaneously one of the most useful and confounding of all Linux commands. It is difficult because its syntax varies from the standard syntax of other Linux commands. It is powerful, however, because it [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=238&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A quick introduction to the most powerful—as well as confusing—aspects of this ubiquitous command.</p>
<p>Published July 2008</p>
<p>The Linux find command is simultaneously one of the most useful and confounding of all Linux commands. It is difficult because its syntax varies from the standard syntax of other Linux commands. It is powerful, however, because it allows you to find files by filename, by file type, by user, and even by time stamp. With the find command, not only are you able to locate files with any combination of these attributes, but you can also perform actions on the files it finds.</p>
<p>The purpose of this article is to simplify the task of learning and using the find command by giving you an overview of its purpose and potential. At the same time, it will provide a basic tutorial and reference for some of the most powerful but confusing aspects of the find command.</p>
<p>[Note: The version of find used for this article is the GNU version, so some details may vary for other versions of find.]<br />
Basic Format</p>
<p>To begin, let’s look at the basic structure of the find command:</p>
<p>find   start_directory  test  options   criteria_to_match<br />
action_to_perform_on_results</p>
<p>In the following command, find will start looking in the current directory, denoted by the “.”, for any file with the “java” extension in its name:</p>
<p>find . -name  &#8220;*.java&#8221;   </p>
<p>Here’s an abbreviated listing of what it found:</p>
<p>find . -name  &#8220;*.java&#8221;<br />
./REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java<br />
./REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java<br />
..</p>
<p>[Note: If you cut and paste from this article to run the find command, you may need to replace the double quotes (“”) using your own keyboard for proper results.]</p>
<p>The following command will do the same thing. In either case, you need to escape the wildcard character to be sure it passes to the find command and is not interpreted by the shell. So, put your search string in quotes, or precede it with a backslash:</p>
<p>find . -name  \*.java</p>
<p>Although all arguments to find are optional, the search will begin by default in the current directory if you do not specify where to begin searching. If you do not specify a test condition, an option, or a value to be matched your results will be either incomplete or indiscriminating.</p>
<p>Running the following three find commands will all yield the same results—a full listing of all files in the current directory and all subdirectories including hidden files:</p>
<p>find<br />
find .<br />
find . -print</p>
<p>This is similar to running an ls command with the -la options. If you want the output of the above commands to contain the full pathnames, perhaps for a backup, you would need to specify the full path for the starting directory:</p>
<p>find /home/bluher -name \*.java<br />
/home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/ConnectionManager.java<br />
/home/bluher/plsql/REGEXPvalidate/src/oracle/otnsamples/plsql/DBManager.java/<br />
&#8230;</p>
<p>You can also specify more than one starting directory in a search string. If run as a user with appropriate privileges, the following command will descend into the /usr, /home, and then /tmp directories to look for all jar files:  </p>
<p>find /usr /home  /tmp -name &#8220;*.jar&#8221;</p>
<p>If you don’t have the appropriate permissions, however, you will generate error messages as you begin to look through many system directories. The following is an example:</p>
<p>find:  /tmp/orbit-root: Permission denied</p>
<p>You can avoid a cluttered output by appending your search string as follows:</p>
<p>find /usr /home  /tmp -name &#8220;*.jar&#8221; 2&gt;/dev/null</p>
<p>This sends all error messages to the null file, thereby providing cleaner output.</p>
<p>By default, find is case sensitive. For a case-insensitive find, substitute the -iname test for the -name test.</p>
<p>find downloads  -iname &#8220;*.gif&#8221;<br />
downloads/.xvpics/Calendar05_enlarged.gif<br />
downloads/lcmgcfexsmall.GIF</p>
<p>You can also search for files by types other than filename. For instance, you can find all the subdirectories in a directory with the following command:</p>
<p>find . -type d          </p>
<p>You can find all the symbolic links in your /usr directory with the following command:</p>
<p>find /usr -type l</p>
<p>This will probably yield a list of more than 3,000 links. Either of the following commands, run with root privileges, will yield a list of links in the /usr directory and the file to which it points:</p>
<p># find /usr/bin  -type l  -name &#8220;z*&#8221; -exec ls  -l {} \;<br />
lrwxrwxrwx 1 root  root 8 Dec 12 23:17 /usr/bin/zsh -&gt; /bin/zsh<br />
lrwxrwxrwx 1 root  root 5 Dec 12 23:17 /usr/bin/zless -&gt; zmore<br />
lrwxrwxrwx 1 root  root 9 Dec 12 23:17 /usr/bin/zcat -&gt; /bin/zcat</p>
<p>find /usr/bin -type  l  -name &#8220;z*&#8221; -ls</p>
<p>The second, shorter command, however, will yield a long file list with directory and inode information as well. We will discuss the use of the -exec and -ls actions later in this article.</p>
<p>Other filetypes that find can locate include</p>
<p>• b—block (buffered) special<br />
• c—character (unbuffered) special<br />
• p—named pipe (FIFO)<br />
• s—socket</p>
<p>Using root as the starting point for a find command can slow down your system significantly. If you really must run such a command, you might run it during low-use time or overnight. You can redirect the output to a file using the following syntax:</p>
<p>find  /   -print &gt; masterfilelist.out</p>
<p>If you find you have erroneously entered a find command that produces copious unwanted output, just interrupt the command by pressing CTRL-C, which stops the most recently executed command.</p>
<p>On an enterprise network with multiple file systems, it is especially good practice to restrict the files that find looks for. Use as many of the options and tests as necessary to reduce the load on your system. Two of the most useful options for this purpose are -xdev and -mount. They narrow the search by preventing find from descending into directories on other file systems such as MS-DOS, CD-ROM, or AFS. This restricts the search to the same type of file system as the startdirectory.</p>
<p>Users on a dual boot system can play with these options if the mount command is run. Assuming that a Windows partition is involved, you could mount it with something like the following command:</p>
<p>mount -t vfat  /dev/sda1 /mnt/msdos</p>
<p>The actual command that you use will depend on how your system is set up. You can verify that the partition was mounted by running df or by executing the following command:</p>
<p>find /mnt/msdos  -name &#8220;*.txt&#8221; 2&gt; /dev/null</p>
<p>You should see a long list of files on the MS Windows partition. Now run the following command with either the -mount or -xdev option:</p>
<p>find / -name  &#8220;*.txt&#8221; -mount 2&gt; /dev/null</p>
<p>or</p>
<p>find / -name  &#8220;*.txt&#8221; -xdev 2&gt; /dev/null</p>
<p>Another possibility is to explicitly tell find which file system to look in using the -fstype test, as in this example:</p>
<p>find / -name  &#8220;*.txt&#8221; -fstype vfat 2&gt; /dev/null</p>
<p>Finding Time</p>
<p>The find command has several options that are used to search for files based on your system’s time stamps. These time stamps include</p>
<p>• mtime—the time that the contents of a file were last modified<br />
• atime—the time that a file was read or accessed<br />
• ctime—the time that a file’s status was changed</p>
<p>While the meaning of mtime and atime is pretty self-evident, ctime requires more explanation. Because the inode maintains metadata on each file, the inode data will change if the metadata related to the file is changed. This could be caused by a range of actions, including the creation of a symbolic link to the file, changing the permissions on a file, or moving the file. Because the contents of the file are not being read or modified in these cases, themtime and atime will not change, but the ctime will change. </p>
<p>Each of these time options needs to be used with a value n, which is specified as -n, n, or +n.</p>
<p>• -n returns less than n<br />
• +n returns greater than n<br />
• n, by itself,returns exactly n matches</p>
<p>Let’s look at some examples to make this clearer. The following command will find all the files modified within the last hour:</p>
<p>find . -mtime -1<br />
./plsql/FORALLSample<br />
./plsql/RegExpDNASample<br />
/plsql/RegExpSample</p>
<p>Running the same command with 1 instead of -1 finds all the files that were modified exactly one hour ago:</p>
<p>find . -mtime 1 </p>
<p>The above command may not yield any results, because it asks for an exact match. The following command looks for the files that were modified more than an hour ago:</p>
<p>find . -mtime +1 </p>
<p>By default, -mtime, -atime, and -ctime refer to the last 24 hours. If, however, they are preceded by the daystart option, the 24-hour period will begin with the start of the current day. You can also look for time stamps that have changed in less than an hour using mmin, amin, and cmin.</p>
<p>If you run the following immediately after logging into your account, you will find all files read less than 1 minute ago:</p>
<p>find . -amin -1<br />
./.bashrc<br />
/.bash_history<br />
./.xauthj5FCx1</p>
<p>It should be noted that locating a file with the find command itself changes that file’s access time as part of its metadata.</p>
<p>You can also find files that have been modified or accessed in comparison to a specific file with the options -newer, -anewer, and –cnewer. This is similar to -mtime, -atime, and –ctime.</p>
<p>• -newer refers to files whose contents have been modified more recently<br />
• -anewer refers to files that have been read more recently<br />
• -cnewer refers to files whose status has changed more recently</p>
<p>To find all the files in your home directory that have been edited in some way since the last tar file, use this command:</p>
<p>find . -newer  backup.tar.gz</p>
<p>Finding Files by Size</p>
<p>The -size option finds files that meet the size criteria specified. To find all user files larger than 5MB, use</p>
<p>find / -size  +5000000c 2&gt; /dev/null<br />
/var/log/lastlog<br />
/var/log/cups/access_log.4<br />
/var/spool/mail/bluher</p>
<p>The “c” at the end reports our results in bytes. By default, find reports size as the number of 512-byte blocks. We could also see the results as the number of kilobytes if we replace the “c” with a “k” or as the number of two-byte words if we use a “w”.</p>
<p>The -size option is frequently used to search for all zero-byte files and move them to the /tmp/zerobyte folder. The following command does just that:</p>
<p>find test -type f  -size 0 -exec mv {} /tmp/zerobyte \;</p>
<p>The -exec action allows find to perform any shell command on the files it encounters. You will see many more examples of its use later in this article. The curly brackets allow each of the empty files to be moved.</p>
<p>The option -empty can also be used to find empty files:</p>
<p>find test -empty<br />
test/foo<br />
test/test</p>
<p>Finding by Permission and Ownership</p>
<p>The find command can be indispensable for monitoring the security of your system. You can look for files with wide open permissions using symbolic or octal notation as follows:</p>
<p>find . -type f  -perm a=rwx -exec ls -l {} \; </p>
<p>or</p>
<p>find . -type f  -perm 777 -exec ls -l {} \;<br />
-rwxrwxrwx 1 bluher  users 0 May 24 14:14 ./test.txt</p>
<p>In the above and the following commands in this section, we are using the -exec ls -l action so you can see the actual permissions of the files returned. The command will find files that are writable by both the “other” and the group:</p>
<p>find plsql -type f  -perm -ug=rw -exec ls -l {} \; 2&gt;/dev/null</p>
<p>or</p>
<p>find plsql -type f  -perm -220 -exec ls -l {} \; 2&gt;/dev/null<br />
-rw-rw-rw- 1 bluher users 4303  Jun  7   2004 plsql/FORALLSample/doc/otn_new.css<br />
-rw-rw-rw- 1 bluher users 10286 Jan  12  2005  plsql/FORALLSample/doc/readme.html<br />
-rw-rw-rw- 1 bluher users 22647 Jan  12  2005  plsql/FORALLSample/src/config.sql<br />
..</p>
<p>This next command will find files that are writable by the user, the group, or both:  </p>
<p>find plsql -type f  -perm /ug=rw -exec ls -l {} \; 2&gt;/dev/null, or,<br />
find plsql -type f  -perm /220 -exec ls -l {} \; 2&gt;/dev/null<br />
-rw-r&#8211;r&#8211; 1 bluher users 21473  May  3 16:02 plsql/regexpvalidate.zip<br />
-rw-rw-rw- 1 bluher users 4303  Jun  7   2004 plsql/FORALLSample/doc/otn_new.css<br />
-rw-rw-rw- 1 bluher users 10286 Jan  12  2005  plsql/FORALLSample/doc/readme.html<br />
-rw-rw-rw- 1 bluher users 22647 Jan  12  2005  plsql/FORALLSample/src/config.sql</p>
<p>You may see the following command cited on the Web and in older manuals:</p>
<p>find . -perm +220  -exec ls -l {} \; 2&gt; /dev/null </p>
<p>The + symbol does the same as the / symbol, although it is now deprecated in newer versions of GNU findutils.</p>
<p>To find all files on your system that are world writable, use the following command:</p>
<p>find / -wholename  &#8216;/proc&#8217; -prune  -o  -type f -perm -0002 -exec ls -l {} \;<br />
-rw-rw-rw- 1 bluher users 4303  Jun  7   2004/home/bluher/plsql/FORALLSample/doc/otn_new.css<br />
-rw-rw-rw- 1 bluher users 10286 Jan  12  2005  /home/bluher/plsql/FORALLSample/doc/readme.html<br />
&#8230;</p>
<p>The fourth permission will be discussed in just a bit, but the “2” in the last field is the “other” field in the file permissions, also known as the write bit. We used a dash before the permission mode of 0002 to indicate that we want to see files with the write permission set for others, regardless of what other permissions are set.</p>
<p>The above command also introduces three new concepts. Using -wholename tests for the file pattern “/proc”, if that pattern is found, -prune  prevents find from descending into that directory. The Boolean “-o” enables find to process the rest of the command for other directories. As there is an implicit and operator (-a)  that is assumed between each expression, expressions following the and will not be evaluated if the expression on the left evaluates to false; hence the need for the -o operator. The Boolean -not, !, is also supported by find, as is the use of parentheses to force precedence.</p>
<p>System administrators frequently use find to search for regular files of specific users or groups using the name or ID of that user or group:</p>
<p>[root] $  find / -type f -user bluher -exec ls -ls {}  \;</p>
<p>Here is a severely abbreviated sample of the output of such a command:</p>
<p>4 -rw-r&#8211;r&#8211; 1 bluher users 48  May  1 03:09  /home/bluher/public_html/.directory<br />
4 -rw-r&#8211;r&#8211; 1 bluher users 925  May  1 03:09 /home/bluher/.profile</p>
<p>You can also use find to look for a file by group:</p>
<p>[root] $ find /  -type f -group users</p>
<p>find / -type d -gid  100</p>
<p>This command will yield a list of directories owned by group ID 100. To find the appropriate uid or gid,  you can run the more or cat command on the /etc/passwd or /etc/group file.</p>
<p>Beyond finding files of specific known users and groups, you may also find it useful to look for files lacking either of these. This next command identifies files that do not have a listing in the /etc/passwd or /etc/group file:</p>
<p>find / -nouser -o  -nogroup</p>
<p>The above command might not actually yield results on your system. It could be used, however, to identify files without a user or group, perhaps after moving files around.</p>
<p>OK, now we can address that extra leading permission mentioned at the beginning of this section.</p>
<p>The SGID and SUID are special access right flags that can be assigned to files and directories on a UNIX-based operating system. They are set to allow ordinary users on a computer system access to execute binary executables with temporarily elevated privileges.</p>
<p>find /  \( -perm -2000 -o -perm -4000 \) -ls<br />
167901   12 -rwsr-xr-x   1 root     root         9340 Jun 16  2006 /usr/bin/rsh<br />
167334   12 -rwxr-sr-x   1 root     tty         10532 May  4  2007 /usr/bin/wall</p>
<p>In the above command, you can see the use of escaped parentheses. You can also see the differences in permissions. The first file has the SGID permission set, and the second file has the SUID permission set. The final action in the above command works like find with the -exec ls -dils action.<br />
Controlling find</p>
<p>Unlike many commands in Linux, find does not require the -r or -R option in order to descend into the subdirectories. It does this by default. However, you may want to limit this behavior at times. For that reason, the options -depth, -maxdepth, and -mindepth and the action -prune may come in handy.</p>
<p>We have already seen how useful -prune can be, so let’s take a look at the -depth, -maxdepth, and -mindepth options.</p>
<p>The -maxdepth and -mindepth options allow you to specify how far down the directory tree you want find to search. If you want find to look in just one level of the directory, you would use the maxdepth option.</p>
<p>You can see the effects of -maxdepth by running the following command to look for log files in the top three levels of the directory tree. This will produce considerably less output than when run without it.</p>
<p>find / -maxdepth 3  -name &#8220;*log&#8221;</p>
<p>You can also tell find to look in directories at least three levels down the directory tree:</p>
<p>find / -mindepth 3  -name &#8220;*log&#8221;</p>
<p>The -depth option ensures that a directory is evaluated before its contents are evaluated. The following command provides an example:</p>
<p>find -name &#8220;*test*&#8221; -depth<br />
./test/test<br />
./test<br />
./localbin/test<br />
./localbin/test_shell_var<br />
./localbin/test.txt<br />
./test2/test/test<br />
./test2/test<br />
./test2</p>
<p>The World of find</p>
<p>We have looked at some of the more useful and somewhat obscure abilities of the find command, but there are additional tasks that find can perform. For instance, there are options that make find compatible with older UNIX versions and other operating systems and that allow you to perform actions such as printing output to multiple files. After reading this article, you now have the background to understand the man page on find, and I encourage you to explore this powerful and useful tool.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/238/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=238&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/12/09/guide-to-linux-find-command-mastery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>Linux 进程和线程查看以及管理</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/29/linux-%e8%bf%9b%e7%a8%8b%e5%92%8c%e7%ba%bf%e7%a8%8b%e6%9f%a5%e7%9c%8b%e4%bb%a5%e5%8f%8a%e7%ae%a1%e7%90%86/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/29/linux-%e8%bf%9b%e7%a8%8b%e5%92%8c%e7%ba%bf%e7%a8%8b%e6%9f%a5%e7%9c%8b%e4%bb%a5%e5%8f%8a%e7%ae%a1%e7%90%86/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 13:19:59 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/2009/10/29/linux-%e8%bf%9b%e7%a8%8b%e5%92%8c%e7%ba%bf%e7%a8%8b%e6%9f%a5%e7%9c%8b%e4%bb%a5%e5%8f%8a%e7%ae%a1%e7%90%86/</guid>
		<description><![CDATA[1.top 命令详解&#38;进程管理 　　top命令查看系统的资源状况 　　load average表示在过去的一段时间内有多少个进程企图独占CPU 　　zombie 进程：不是异常情况。一个进程从创建到结束在最后那一段时间遍是僵尸。留在内存中等待父进程取的东西便是僵尸。任何程序都有僵尸状态，它占用一点内存资源，仅仅是表象而已不必害怕。如果程序有问题有机会遇见，解决大批量僵尸简单有效的办法是重起。kill是无任何效果的stop模式：与sleep进程应区别，sleep会主动放弃cpu，而stop是被动放弃cpu ，例单步跟踪，stop（暂停）的进程是无法自己回到运行状态的。 　　cpu states： * nice：让出百分比 * irq：中断处理占用 * idle：空间占用百分比 * iowait：输入输出等待（如果它很大说明外存有瓶颈，需要升级硬盘（SCSI）） * Mem：内存情况 　　设计思想：把资源省下来不用便是浪费，如添加内存后free值会不变，buff值会增大。判断物理内存够不够，看交换分区的使用状态。 　　交互命令： * [Space]立即刷新显示 * [h]显示帮助屏幕 * [k] 杀死某进程。你会被提示输入进程 ID 以及要发送给它的信号。 一般的终止进程可以使用15信号；如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。 * [n] 改变显示的进程数量。你会被提示输入数量。 * [u] 按用户排序。 * [M] 按内存用量排序。 * [o][O] 改变显示项目的顺序。 * [P] 根据CPU使用百分比大小进行排序。 * [T] 根据时间/累计时间进行排序。 * [Ctrl+L] 擦除并且重写屏幕。 * [q] [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=237&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>1.top 命令详解&amp;进程管理</p>
<p>　　top命令查看系统的资源状况</p>
<p>　　load average表示在过去的一段时间内有多少个进程企图独占CPU</p>
<p>　　zombie 进程：不是异常情况。一个进程从创建到结束在最后那一段时间遍是僵尸。留在内存中等待父进程取的东西便是僵尸。任何程序都有僵尸状态，它占用一点内存资源，仅仅是表象而已不必害怕。如果程序有问题有机会遇见，解决大批量僵尸简单有效的办法是重起。kill是无任何效果的stop模式：与sleep进程应区别，sleep会主动放弃cpu，而stop是被动放弃cpu ，例单步跟踪，stop（暂停）的进程是无法自己回到运行状态的。</p>
<p>　　cpu states：</p>
<p>    * nice：让出百分比<br />
    * irq：中断处理占用<br />
    * idle：空间占用百分比<br />
    * iowait：输入输出等待（如果它很大说明外存有瓶颈，需要升级硬盘（SCSI））<br />
    * Mem：内存情况</p>
<p>　　设计思想：把资源省下来不用便是浪费，如添加内存后free值会不变，buff值会增大。判断物理内存够不够，看交换分区的使用状态。</p>
<p>　　交互命令：</p>
<p>    * [Space]立即刷新显示<br />
    * [h]显示帮助屏幕<br />
    * [k] 杀死某进程。你会被提示输入进程 ID 以及要发送给它的信号。 一般的终止进程可以使用15信号；如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。<br />
    * [n] 改变显示的进程数量。你会被提示输入数量。<br />
    * [u] 按用户排序。<br />
    * [M] 按内存用量排序。<br />
    * [o][O] 改变显示项目的顺序。<br />
    * [P] 根据CPU使用百分比大小进行排序。<br />
    * [T] 根据时间/累计时间进行排序。<br />
    * [Ctrl+L] 擦除并且重写屏幕。<br />
    * [q] 退出程序。<br />
    * [r] 重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低，反之则可以使该进程拥有更高的优先权。默认值是10。<br />
    * [S] 切换到累计模式。<br />
    * [s] 改变两次刷新之间的延迟时间。系统将提示用户输入新的时间，单位为s。如果有小数，就换算成m s。输入0值则系统将不断刷新，默认值是5 s。需要注意的是如果设置太小的时间，很可能会引起不断刷新，从而根本来不及看清显示的情况，而且系统负载也会大大增加。</p>
<p>　　缩写含义：</p>
<p>    * PID每个进程的ID<br />
    * USER进程所有者的用户名<br />
    * PRI每个进程的优先级别<br />
    * NI每个优先级的值<br />
    * SIZE 进程的代码大小加上数据大小再加上堆栈空间大小的总数，单位是KB RSS 进程占用的物理内存的总数量，单位是KB<br />
    * SHARE进程使用共享内存的数量<br />
    * STAT 进程的状态。其中S代表休眠状态；D代表不可中断的休眠状态；R代表运行状态；Z代表僵死状态；T代表停止或跟踪状态<br />
    * %CPU进程自最近一次刷新以来所占用的CPU时间和总时间的百分比<br />
    * %MEM进程占用的物理内存占总内存的百分比<br />
    * TIME进程自启动以来所占用的总CPU时间<br />
    * CPU CPU标识<br />
    * COMMAND进程的命令名称</p>
<p>2. ps命令列进程。</p>
<p>　　ps ax  ：tty值为“？”是守护进程，叫deamon 无终端，大多系统服务是此进程，内核态进程是看不到的，例木马。</p>
<p>　　ps axf  ：看进程树，以树形方式现实进程列表敲 ，init是1号进程，系统所有进程都是它派生的，杀不掉。</p>
<p>　　ps axm ：会把线程列出来。在linux下进程和线程是统一的，是轻量级进程的两种方式。</p>
<p>　　ps axu ：显示进程的详细状态。</p>
<p>　　vsz：说此进程一共占用了多大物理内存。</p>
<p>　　rss：请求常驻内存多少</p>
<p>　　3.终止进程：  kill pid   本质是协商退出！（并不是强制退出）</p>
<p>　　全：kill -信号pid</p>
<p>　　kill –KILL pid是强制退出。</p>
<p>　　例如编写一kill杀不掉的程序</p>
<p>　　#!/bin/sh</p>
<p>　　while true j do</p>
<p>　　echo –n “.”</p>
<p>　　sleep 1</p>
<p>　　done</p>
<p>　　#!/bin/sh trap “”15   ##捕获15号进程，kill就是15号进程</p>
<p>　　while true j do</p>
<p>　　echo -n “.”</p>
<p>　　sleep 1</p>
<p>　　done</p>
<p>　　4.修改进程优先级：</p>
<p>　　nice 命令 每个进程都有优先权，权值越小优先级越高。</p>
<p>　　nice –调整值命令      ##范围“-20~19”</p>
<p>　　linux图形界面的优先级并不是最高的，它仅是一进程。</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/237/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=237&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/29/linux-%e8%bf%9b%e7%a8%8b%e5%92%8c%e7%ba%bf%e7%a8%8b%e6%9f%a5%e7%9c%8b%e4%bb%a5%e5%8f%8a%e7%ae%a1%e7%90%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>Apache的httpd进程占用大量内存原因及其解决方案</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/23/apache%e7%9a%84httpd%e8%bf%9b%e7%a8%8b%e5%8d%a0%e7%94%a8%e5%a4%a7%e9%87%8f%e5%86%85%e5%ad%98%e5%8e%9f%e5%9b%a0%e5%8f%8a%e5%85%b6%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/23/apache%e7%9a%84httpd%e8%bf%9b%e7%a8%8b%e5%8d%a0%e7%94%a8%e5%a4%a7%e9%87%8f%e5%86%85%e5%ad%98%e5%8e%9f%e5%9b%a0%e5%8f%8a%e5%85%b6%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 16:48:30 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Server]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=235</guid>
		<description><![CDATA[问题：为什么服务器在连续运行多天后或访问峰值后，进程中的一个Apache.exe占用内存几百兆不减少？ 分析：通常在“Windows任务管理器－进程”中可以看到两个apache.exe进程，一个是父进程、一个是子进程，父进程接到访问请求后，将请求交由子进程处理。MaxRequestsPerChild这个指令设定一个独立的子进程将能处理的请求数量。在处理 “MaxRequestsPerChild 数字”个请求之后，子进程将会被父进程终止，这时候子进程占用的内存就会释放，如果再有访问请求，父进程会重新产生子进程进行处理。 如果MaxRequestsPerChild缺省设为0(无限)或较大的数字(例如10000以上)可以使每个子进程处理更多的请求，不会因为不断终止、启动子进程降低访问效率，但MaxRequestsPerChild设置为0时，如果占用了200～300M内存，即使负载下来时占用的内存也不会减少。内存较大的服务器可以设置为0或较大的数字。内存较小的服务器不妨设置成30、50、100，以防内存溢出。 　　用记事本打开apache2confhttpd.conf，查找MaxRequestsPerChild，将MaxRequestsPerChild 0改成MaxRequestsPerChild 50，重启apache即可。<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=235&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>问题：为什么服务器在连续运行多天后或访问峰值后，进程中的一个Apache.exe占用内存几百兆不减少？</p>
<p>分析：通常在“Windows任务管理器－进程”中可以看到两个apache.exe进程，一个是父进程、一个是子进程，父进程接到访问请求后，将请求交由子进程处理。MaxRequestsPerChild这个指令设定一个独立的子进程将能处理的请求数量。在处理 “MaxRequestsPerChild 数字”个请求之后，子进程将会被父进程终止，这时候子进程占用的内存就会释放，如果再有访问请求，父进程会重新产生子进程进行处理。</p>
<p>如果MaxRequestsPerChild缺省设为0(无限)或较大的数字(例如10000以上)可以使每个子进程处理更多的请求，不会因为不断终止、启动子进程降低访问效率，但MaxRequestsPerChild设置为0时，如果占用了200～300M内存，即使负载下来时占用的内存也不会减少。内存较大的服务器可以设置为0或较大的数字。内存较小的服务器不妨设置成30、50、100，以防内存溢出。</p>
<p>　　用记事本打开apache2confhttpd.conf，查找MaxRequestsPerChild，将MaxRequestsPerChild 0改成MaxRequestsPerChild 50，重启apache即可。</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/235/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=235&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/23/apache%e7%9a%84httpd%e8%bf%9b%e7%a8%8b%e5%8d%a0%e7%94%a8%e5%a4%a7%e9%87%8f%e5%86%85%e5%ad%98%e5%8e%9f%e5%9b%a0%e5%8f%8a%e5%85%b6%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>Apache配置文件：http.conf配置详解</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/23/apache%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6%ef%bc%9ahttp-conf%e9%85%8d%e7%bd%ae%e8%af%a6%e8%a7%a3/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/23/apache%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6%ef%bc%9ahttp-conf%e9%85%8d%e7%bd%ae%e8%af%a6%e8%a7%a3/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 16:41:03 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Server]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=233</guid>
		<description><![CDATA[Apache的配置文件http.conf参数含义详解 Apache的配置由httpd.conf文件配置，因此下面的配置指令都是在httpd.conf文件中修改。 主站点的配置(基本配置) (1) 基本配置: ServerRoot &#8220;/mnt/software/apache2&#8243; #你的apache软件安装的位置。其它指定的目录如果没有指定绝对路径，则目录是相对于该目录。 PidFile logs/httpd.pid #第一个httpd进程(所有其他进程的父进程)的进程号文件位置。 Listen 80 #服务器监听的端口号。 ServerName www.clusting.com:80 #主站点名称（网站的主机名）。 ServerAdmin admin@clusting.com #管理员的邮件地址。 DocumentRoot &#8220;/mnt/web/clusting&#8221; #主站点的网页存储位置。 以下是对主站点的目录进行访问控制： Options FollowSymLinks AllowOverride None Order allow,deny Allow from all 在上面这段目录属性配置中，主要有下面的选项： Options：配置在特定目录使用哪些特性，常用的值和基本含义如下： ExecCGI: 在该目录下允许执行CGI脚本。 FollowSymLinks: 在该目录下允许文件系统使用符号连接。 Indexes: 当用户访问该目录时，如果用户找不到DirectoryIndex指定的主页文件(例如index.html),则返回该目录下的文件列表给用户。 SymLinksIfOwnerMatch: 当使用符号连接时，只有当符号连接的文件拥有者与实际文件的拥有者相同时才可以访问。 其它可用值和含义请参阅：http://www.clusting.com/Apache/ApacheManual/mod/core.html#options AllowOverride：允许存在于.htaccess文件中的指令类型(.htaccess文件名是可以改变的，其文件名由AccessFileName指令决定)： None: 当AllowOverride被设置为None时。不搜索该目录下的.htaccess文件（可以减小服务器开销）。 All: 在.htaccess文件中可以使用所有的指令。 其他的可用值及含义(如：Options FileInfo AuthConfig Limit等)，请参看： http://www.clusting.com/Apache/ApacheManual/mod/core.html#AllowOverride Order：控制在访问时Allow和Deny两个访问规则哪个优先： [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=233&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Apache的配置文件http.conf参数含义详解</p>
<p>Apache的配置由httpd.conf文件配置，因此下面的配置指令都是在httpd.conf文件中修改。<br />
主站点的配置(基本配置)</p>
<p>(1) 基本配置:<br />
ServerRoot &#8220;/mnt/software/apache2&#8243; #你的apache软件安装的位置。其它指定的目录如果没有指定绝对路径，则目录是相对于该目录。</p>
<p>PidFile logs/httpd.pid #第一个httpd进程(所有其他进程的父进程)的进程号文件位置。</p>
<p>Listen 80 #服务器监听的端口号。</p>
<p>ServerName www.clusting.com:80 #主站点名称（网站的主机名）。</p>
<p>ServerAdmin admin@clusting.com #管理员的邮件地址。</p>
<p>DocumentRoot &#8220;/mnt/web/clusting&#8221; #主站点的网页存储位置。</p>
<p>以下是对主站点的目录进行访问控制：</p>
<p>Options FollowSymLinks<br />
AllowOverride None<br />
Order allow,deny<br />
Allow from all</p>
<p>在上面这段目录属性配置中，主要有下面的选项：</p>
<p>Options：配置在特定目录使用哪些特性，常用的值和基本含义如下：</p>
<p>ExecCGI: 在该目录下允许执行CGI脚本。</p>
<p>FollowSymLinks: 在该目录下允许文件系统使用符号连接。</p>
<p>Indexes: 当用户访问该目录时，如果用户找不到DirectoryIndex指定的主页文件(例如index.html),则返回该目录下的文件列表给用户。</p>
<p>SymLinksIfOwnerMatch: 当使用符号连接时，只有当符号连接的文件拥有者与实际文件的拥有者相同时才可以访问。</p>
<p>其它可用值和含义请参阅：http://www.clusting.com/Apache/ApacheManual/mod/core.html#options</p>
<p>AllowOverride：允许存在于.htaccess文件中的指令类型(.htaccess文件名是可以改变的，其文件名由AccessFileName指令决定)：<br />
None: 当AllowOverride被设置为None时。不搜索该目录下的.htaccess文件（可以减小服务器开销）。</p>
<p>All: 在.htaccess文件中可以使用所有的指令。</p>
<p>其他的可用值及含义(如：Options FileInfo AuthConfig Limit等)，请参看： http://www.clusting.com/Apache/ApacheManual/mod/core.html#AllowOverride</p>
<p>Order：控制在访问时Allow和Deny两个访问规则哪个优先：</p>
<p>Allow：允许访问的主机列表(可用域名或子网，例如：Allow from 192.168.0.0/16)。</p>
<p>Deny：拒绝访问的主机列表。</p>
<p>更详细的用法可参看：http://www.clusting.com/Apache/ApacheManual/mod/mod_access.html#order</p>
<p>DirectoryIndex index.html index.htm index.php #主页文件的设置（本例将主页文件设置为：index.html,index.htm和index.php）</p>
<p>(2) 服务器的优化 (MPM: Multi-Processing Modules)<br />
apache2主要的优势就是对多处理器的支持更好，在编译时同过使用–with-mpm选项来决定apache2的工作模式。如果知道当前的apache2使用什么工作机制，可以通过httpd -l命令列出apache的所有模块，就可以知道其工作方式：</p>
<p>prefork：如果httpd -l列出prefork.c，则需要对下面的段进行配置：</p>
<p>StartServers 5 #启动apache时启动的httpd进程个数。</p>
<p>MinSpareServers 5 #服务器保持的最小空闲进程数。</p>
<p>MaxSpareServers 10 #服务器保持的最大空闲进程数。</p>
<p>MaxClients 150 #最大并发连接数。</p>
<p>MaxRequestsPerChild 1000 #每个子进程被请求服务多少次后被kill掉。0表示不限制，推荐设置为1000。</p>
<p>在该工作模式下，服务器启动后起动5个httpd进程(加父进程共6个，通过ps -ax|grep httpd命令可以看到)。当有用户连接时，apache会使用一个空闲进程为该连接服务，同时父进程会fork一个子进程。直到内存中的空闲进程达到 MaxSpareServers。该模式是为了兼容一些旧版本的程序。我缺省编译时的选项。<br />
worker：如果httpd -l列出worker.c，则需要对下面的段进行配置：</p>
<p>StartServers 2 #启动apache时启动的httpd进程个数。</p>
<p>MaxClients 150 #最大并发连接数。<br />
IXDBA.NET社区论坛</p>
<p>MinSpareThreads 25 #服务器保持的最小空闲线程数。</p>
<p>MaxSpareThreads 75 #服务器保持的最大空闲线程数。</p>
<p>ThreadsPerChild 25 #每个子进程的产生的线程数。</p>
<p>MaxRequestsPerChild 0 #每个子进程被请求服务多少次后被kill掉。0表示不限制，推荐设置为1000。</p>
<p>该模式是由线程来监听客户的连接。当有新客户连接时，由其中的一个空闲线程接受连接。服务器在启动时启动两个进程，每个进程产生的线程数是固定的 (ThreadsPerChild决定)，因此启动时有50个线程。当50个线程不够用时，服务器自动fork一个进程，再产生25个线程。</p>
<p>perchild：如果httpd -l列出perchild.c，则需要对下面的段进行配置：</p>
<p>NumServers 5 #服务器启动时启动的子进程数</p>
<p>StartThreads 5 #每个子进程启动时启动的线程数</p>
<p>MinSpareThreads 5 #内存中的最小空闲线程数</p>
<p>MaxSpareThreads 10 #最大空闲线程数</p>
<p>MaxThreadsPerChild 2000 #每个线程最多被请求多少次后退出。0不受限制。</p>
<p>MaxRequestsPerChild 10000 #每个子进程服务多少次后被重新fork。0表示不受限制。</p>
<p>该模式下，子进程的数量是固定的，线程数不受限制。当客户端连接到服务器时，又空闲的线程提供服务。 如果空闲线程数不够，子进程自动产生线程来为新的连接服务。该模式用于多站点服务器。<br />
(3) HTTP返头回信息配置:</p>
<p>ServerTokens Prod #该参数设置http头部返回的apache版本信息，可用的值和含义如下：</p>
<p>Prod：仅软件名称，例如：apache<br />
Major：包括主版本号，例如：apache/2<br />
Minor：包括次版本号，例如：apache/2.0<br />
Min：仅apache的完整版本号，例如：apache/2.0.54<br />
OS：包括操作系统类型，例如：apache/2.0.54（Unix）<br />
Full：包括apache支持的模块及模块版本号，例如：Apache/2.0.54 (Unix) mod_ssl/2.0.54 OpenSSL/0.9.7g<br />
ServerSignature Off #在页面产生错误时是否出现服务器版本信息。推荐设置为Off</p>
<p>(4) 持久性连接设置</p>
<p>KeepAlive On #开启持久性连接功能。即当客户端连接到服务器，下载完数据后仍然保持连接状态。</p>
<p>MaxKeepAliveRequests 100 #一个连接服务的最多请求次数。</p>
<p>KeepAliveTimeout 30 #持续连接多长时间，该连接没有再请求数据，则断开该连接。缺省为15秒。</p>
<p>别名设置<br />
对于不在DocumentRoot指定的目录内的页面，既可以使用符号连接，也可以使用别名。别名的设置如下：</p>
<p>Alias /download/ &#8220;/var/www/download/&#8221; #访问时可以输入:http://www.custing.com/download/</p>
<p> #对该目录进行访问控制设置<br />
Options Indexes MultiViews<br />
AllowOverride AuthConfig<br />
Order allow,deny<br />
Allow from all</p>
<p>CGI设置</p>
<p>scrīptAlias /cgi-bin/ &#8220;/mnt/software/apache2/cgi-bin/&#8221; # 访问时可以：http://www.clusting.com/cgi-bin/ 。但是该目录下的CGI脚本文件要加可执行权限！</p>
<p> #设置目录属性<br />
AllowOverride None<br />
Options None<br />
Order allow,deny<br />
Allow from all</p>
<p>个人主页的设置 (public_html)</p>
<p>UserDir public_html (间用户的主页存储在用户主目录下的public_html目录下 URL http://www.clusting.com/~bearzhang/file.html 将读取 /home/bearzhang/public_html/file.html 文件)</p>
<p>chmod 755 /home/bearzhang #</p>
<p>使其它用户能够读取该文件。</p>
<p>UserDir /var/html (the URL http://www.clusting.com/~bearzhang/file.html 将读取 /var/html/bearzhang/file.html)</p>
<p>UserDir /var/www/*/docs (the URL http://www.clusting.com/~bearzhang/file.html 将读取 /var/www/bearzhang/docs/file.html)</p>
<p>日志的设置</p>
<p>(1)错误日志的设置<br />
ErrorLog logs/error_log #日志的保存位置<br />
IXDBA.NET社区论坛<br />
LogLevel warn #日志的级别</p>
<p>显示的格式日下：<br />
[Mon Oct 10 15:54:29 2005] [error] [client 192.168.10.22] access to /download/ failed, reason: user admin not allowed access</p>
<p>(2)访问日志设置</p>
<p>日志的缺省格式有如下几种：<br />
LogFormat &#8220;%h %l %u %t &#8220;%r&#8221; %&gt;s %b &#8220;%{Referer}i&#8221; &#8220;%{User-Agent}i&#8221;" combined<br />
LogFormat &#8220;%h %l %u %t &#8220;%r&#8221; %&gt;s %b&#8221; common #common为日志格式名称<br />
LogFormat &#8220;%{Referer}i -&gt; %U&#8221; referer<br />
LogFormat &#8220;%{User-agent}i&#8221; agent<br />
CustomLog logs/access_log common</p>
<p>格式中的各个参数如下：</p>
<p>%h –客户端的ip地址或主机名</p>
<p>%l –The 这是由客户端 identd 判断的RFC 1413身份，输出中的符号 &#8220;-&#8221; 表示此处信息无效。</p>
<p>%u –由HTTP认证系统得到的访问该网页的客户名。有认证时才有效，输出中的符号 &#8220;-&#8221; 表示此处信息无效。</p>
<p>%t –服务器完成对请求的处理时的时间。</p>
<p>&#8220;%r&#8221; –引号中是客户发出的包含了许多有用信息的请求内容。</p>
<p>%&gt;s –这个是服务器返回给客户端的状态码。</p>
<p>%b –最后这项是返回给客户端的不包括响应头的字节数。</p>
<p>&#8220;%{Referer}i&#8221; –此项指明了该请求是从被哪个网页提交过来的。</p>
<p>&#8220;%{User-Agent}i&#8221; –此项是客户浏览器提供的浏览器识别信息。</p>
<p>下面是一段访问日志的实例：<br />
192.168.10.22 – bearzhang [10/Oct/2005:16:53:06 +0800] &#8220;GET /download/ HTTP/1.1&#8243; 200 1228<br />
192.168.10.22 – &#8211; [10/Oct/2005:16:53:06 +0800] &#8220;GET /icons/blank.gif HTTP/1.1&#8243; 304 -<br />
192.168.10.22 – &#8211; [10/Oct/2005:16:53:06 +0800] &#8220;GET /icons/back.gif HTTP/1.1&#8243; 304 -</p>
<p>各参数的详细解释，请参阅：http://www.clusting.com/Apache/ApacheManual/logs.html</p>
<p>用户认证的配置<br />
(1)in the httpd.conf:<br />
AccessFileName .htaccess<br />
………<br />
Alias /download/ &#8220;/var/www/download/&#8221;</p>
<p>Options Indexes<br />
AllowOverride AuthConfig</p>
<p>(2) create a password file:<br />
/usr/local/apache2/bin/htpasswd -c /var/httpuser/passwords bearzhang</p>
<p>(3)onfigure the server to request a password and tell the server which users are allowed access.<br />
vi /var/www/download/.htaccess:<br />
AuthType Basic<br />
AuthName &#8220;Restricted Files&#8221;<br />
AuthUserFile /var/httpuser/passwords<br />
Require user bearzhang<br />
#Require valid-user #all valid user</p>
<p>虚拟主机的配置<br />
(1)基于IP地址的虚拟主机配置<br />
Listen 80</p>
<p>DocumentRoot /www/example1<br />
ServerName www.example1.com</p>
<p>DocumentRoot /www/example2<br />
ServerName www.example2.org</p>
<p>(2) 基于IP和多端口的虚拟主机配置<br />
Listen 172.20.30.40:80<br />
Listen 172.20.30.40:8080<br />
Listen 172.20.30.50:80<br />
Listen 172.20.30.50:8080</p>
<p>DocumentRoot /www/example1-80<br />
ServerName www.example1.com</p>
<p>DocumentRoot /www/example1-8080<br />
ServerName www.example1.com</p>
<p>DocumentRoot /www/example2-80<br />
ServerName www.example1.org</p>
<p>DocumentRoot /www/example2-8080<br />
ServerName www.example2.org</p>
<p>(3)单个IP地址的服务器上基于域名的虚拟主机配置：<br />
# Ensure that Apache listens on port 80<br />
Listen 80</p>
<p># Listen for virtual host requests on all IP addresses<br />
NameVirtualHost *:80</p>
<p>DocumentRoot /www/example1<br />
ServerName www.example1.com<br />
ServerAlias example1.com. *.example1.com<br />
# Other directives here</p>
<p>DocumentRoot /www/example2<br />
ServerName www.example2.org<br />
# Other directives here</p>
<p>(4)在多个IP地址的服务器上配置基于域名的虚拟主机：<br />
Listen 80</p>
<p># This is the &#8220;main&#8221; server running on 172.20.30.40<br />
ServerName server.domain.com<br />
DocumentRoot /www/mainserver</p>
<p># This is the other address<br />
NameVirtualHost 172.20.30.50</p>
<p>DocumentRoot /www/example1<br />
ServerName www.example1.com<br />
# Other directives here …</p>
<p>IXDBA.NET社区论坛</p>
<p>DocumentRoot /www/example2<br />
ServerName www.example2.org<br />
# Other directives here …</p>
<p>(5)在不同的端口上运行不同的站点(基于多端口的服务器上配置基于域名的虚拟主机)：<br />
Listen 80<br />
Listen 8080</p>
<p>NameVirtualHost 172.20.30.40:80<br />
NameVirtualHost 172.20.30.40:8080</p>
<p>ServerName www.example1.com<br />
DocumentRoot /www/domain-80</p>
<p>ServerName www.example1.com<br />
DocumentRoot /www/domain-8080</p>
<p>ServerName www.example2.org<br />
DocumentRoot /www/otherdomain-80</p>
<p>ServerName www.example2.org<br />
DocumentRoot /www/otherdomain-8080</p>
<p>(6)基于域名和基于IP的混合虚拟主机的配置:<br />
Listen 80</p>
<p>NameVirtualHost 172.20.30.40</p>
<p>DocumentRoot /www/example1<br />
ServerName www.example1.com</p>
<p>DocumentRoot /www/example2<br />
ServerName www.example2.org</p>
<p>DocumentRoot /www/example3<br />
ServerName www.example3.net</p>
<p>SSL加密的配置</p>
<p>首先在配置之前先来了解一些基本概念：</p>
<p>证书的概念：首先要有一个根证书，然后用根证书来签发服务器证书和客户证书，一般理解：服务器证书和客户证书是平级关系。SSL必须安装服务器证书来认证。 因此：在此环境中，至少必须有三个证书：根证书，服务器证书，客户端证书。在生成证书之前，一般会有一个私钥，同时用私钥生成证书请求，再利用证书服务器的根证来签发证书。</p>
<p>SSL所使用的证书可以自己生成，也可以通过一个商业性<br />
CA（如Verisign 或 Thawte）签署证书。</p>
<p>签发证书的问题：如果使用的是商业证书，具体的签署方法请查看相关销售商的说明；如果是知己签发的证书，可以使用openssl自带的CA.sh脚本工具。<br />
IXDBA.NET社区论坛</p>
<p>如果不为单独的客户端签发证书，客户端证书可以不用生成，客户端与服务器端使用相同的证书。<br />
(1) conf/ssl.conf 配置文件中的主要参数配置如下：</p>
<p>Listen 443<br />
SSLPassPhraseDialog buildin<br />
#SSLPassPhraseDialog exec:/path/to/program<br />
SSLSessionCache dbm:/usr/local/apache2/logs/ssl_scache<br />
SSLSessionCacheTimeout 300<br />
SSLMutex file:/usr/local/apache2/logs/ssl_mutex</p>
<p># General setup for the virtual host<br />
DocumentRoot &#8220;/usr/local/apache2/htdocs&#8221;<br />
ServerName www.example.com:443<br />
ServerAdmin you@example.com<br />
ErrorLog /usr/local/apache2/logs/error_log<br />
TransferLog /usr/local/apache2/logs/access_log</p>
<p>SSLEngine on<br />
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL</p>
<p>SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt<br />
SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key<br />
CustomLog /usr/local/apache2/logs/ssl_request_log &#8220;%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x &#8220;%r&#8221; %b&#8221;</p>
<p>(2) 创建和使用自签署的证书：<br />
a.Create a RSA private key for your Apache server<br />
/usr/local/openssl/bin/openssl genrsa -des3 -out /usr/local/apache2/conf/ssl.key/server.key 1024</p>
<p>b. Create a Certificate Signing Request (CSR)<br />
/usr/local/openssl/bin/openssl req -new -key /usr/local/apache2/conf/ssl.key/server.key -out /usr/local/apache2/conf/ssl.key/server.csr</p>
<p>c. Create a self-signed CA Certificate (X509 structure) with the RSA key of the CA<br />
/usr/local/openssl/bin/openssl req -x509 -days 365 -key /usr/local/apache2/conf/ssl.key/server.key -in /usr/local/apache2/conf/ssl.key/server.csr -out /usr/local/apache2/conf/ssl.crt/server.crt</p>
<p>/usr/local/openssl/bin/openssl genrsa 1024 -out server.key<br />
/usr/local/openssl/bin/openssl req -new -key server.key -out server.csr<br />
/usr/local/openssl/bin/openssl req -x509 -days 365 -key server.key -in server.csr -out server.crt</p>
<p>(3) 创建自己的CA（认证证书），并使用该CA来签署服务器的证书。<br />
mkdir /CA<br />
cd /CA<br />
cp openssl-0.9.7g/apps/CA.sh /CA<br />
./CA.sh -newca<br />
openssl genrsa -des3 -out server.key 1024<br />
openssl req -new -key server.key -out server.csr<br />
cp server.csr newreq.pem<br />
./CA.sh -sign<br />
cp newcert.pem /usr/local/apache2/conf/ssl.crt/server.crt<br />
cp server.key /usr/local/apache2/conf/ssl.key/</p>
<p>原文链接：http://www.demi.cn/archives/482 </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/233/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=233&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/23/apache%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6%ef%bc%9ahttp-conf%e9%85%8d%e7%bd%ae%e8%af%a6%e8%a7%a3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>innerHTML、innerText和outerHTML、outerText的区别</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/22/innerhtml%e3%80%81innertext%e5%92%8couterhtml%e3%80%81outertext%e7%9a%84%e5%8c%ba%e5%88%ab/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/22/innerhtml%e3%80%81innertext%e5%92%8couterhtml%e3%80%81outertext%e7%9a%84%e5%8c%ba%e5%88%ab/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 21:21:59 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[Software Testing]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=229</guid>
		<description><![CDATA[innerHTML、innerText和outerHTML、outerText的区别 * innerHTML 设置或获取位于对象起始和结束标签内的 HTML * outerHTML 设置或获取对象及其内容的 HTML 形式 * innerText 设置或获取位于对象起始和结束标签内的文本 * outerText 设置(包括标签)或获取(不包括标签)对象的文本 对于一个id为&#8221;testdiv&#8221;的div来说，outerHTML、innerHTML以及innerTEXT三者的区别可以通过下图展示出来：<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=229&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>innerHTML、innerText和outerHTML、outerText的区别</p>
<p>    * innerHTML 设置或获取位于对象起始和结束标签内的 HTML<br />
    * outerHTML 设置或获取对象及其内容的 HTML 形式<br />
    * innerText 设置或获取位于对象起始和结束标签内的文本<br />
    * outerText 设置(包括标签)或获取(不包括标签)对象的文本</p>
<p>对于一个id为&#8221;testdiv&#8221;的div来说，outerHTML、innerHTML以及innerTEXT三者的区别可以通过下图展示出来：</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/229/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=229&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/22/innerhtml%e3%80%81innertext%e5%92%8couterhtml%e3%80%81outertext%e7%9a%84%e5%8c%ba%e5%88%ab/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>QTP： 如何获取所有打开的excel对象</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/22/qtp%ef%bc%9a-%e5%a6%82%e4%bd%95%e8%8e%b7%e5%8f%96%e6%89%80%e6%9c%89%e6%89%93%e5%bc%80%e7%9a%84excel%e5%af%b9%e8%b1%a1/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/22/qtp%ef%bc%9a-%e5%a6%82%e4%bd%95%e8%8e%b7%e5%8f%96%e6%89%80%e6%9c%89%e6%89%93%e5%bc%80%e7%9a%84excel%e5%af%b9%e8%b1%a1/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 21:19:25 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[QuickTest Pro]]></category>
		<category><![CDATA[Software Testing]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=227</guid>
		<description><![CDATA[Set excels = getObject( ,&#8221;Excel.Application&#8221;) For each excelWorkBook in excels.WorkBooks msgbox excelWorkBook.FullName Next<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=227&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Set excels = getObject( ,&#8221;Excel.Application&#8221;)</p>
<p>For each excelWorkBook in excels.WorkBooks<br />
    msgbox excelWorkBook.FullName<br />
Next </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/227/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=227&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/22/qtp%ef%bc%9a-%e5%a6%82%e4%bd%95%e8%8e%b7%e5%8f%96%e6%89%80%e6%9c%89%e6%89%93%e5%bc%80%e7%9a%84excel%e5%af%b9%e8%b1%a1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>qtp注意点</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/22/qtp%e6%b3%a8%e6%84%8f%e7%82%b9/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/22/qtp%e6%b3%a8%e6%84%8f%e7%82%b9/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 21:18:47 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[QuickTest Pro]]></category>
		<category><![CDATA[Software Testing]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=225</guid>
		<description><![CDATA[1、函数和变量不能重名， 否则造成运行失败 2、当使用createObject方法的时候， 一定记得释放空间， 否则出现内存不足的错误 例如 Set fso = CreateObject(&#8220;Scripting.FileSystemObject&#8221;) Set fso = nothing<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=225&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>1、函数和变量不能重名， 否则造成运行失败<br />
2、当使用createObject方法的时候， 一定记得释放空间， 否则出现内存不足的错误<br />
例如 Set fso = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)<br />
    Set fso = nothing</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/225/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=225&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/22/qtp%e6%b3%a8%e6%84%8f%e7%82%b9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>QTP的if 语句</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/22/qtp%e7%9a%84if-%e8%af%ad%e5%8f%a5/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/22/qtp%e7%9a%84if-%e8%af%ad%e5%8f%a5/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 21:18:14 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[QuickTest Pro]]></category>
		<category><![CDATA[Software Testing]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=223</guid>
		<description><![CDATA[dim i i = 50 If 100&#62;= i =&#62;1 Then &#8216; 100&#62;= i =&#62;1为 false msgbox i End If i =10 If 10 =&#60; i =&#60;122 Then &#039; 10 =&#60; i =&#60;122 为 true msgbox &#34;kkk&#34; End If 运行结果为： 弹出对话框 kkk<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=223&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>dim i<br />
i = 50<br />
If 100&gt;= i =&gt;1 Then   &#8216; 100&gt;= i =&gt;1为 false<br />
    msgbox i<br />
End If</p>
<p>i =10<br />
If 10 =&lt; i =&lt;122 Then   &#039; 10 =&lt; i =&lt;122 为 true<br />
    msgbox &quot;kkk&quot;<br />
End If</p>
<p>运行结果为： 弹出对话框 kkk</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/223/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=223&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/22/qtp%e7%9a%84if-%e8%af%ad%e5%8f%a5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
		<item>
		<title>关于在QTP10.0中使用dom html</title>
		<link>http://davidzhangzy.wordpress.com/2009/10/22/%e5%85%b3%e4%ba%8e%e5%9c%a8qtp10-0%e4%b8%ad%e4%bd%bf%e7%94%a8dom-html/</link>
		<comments>http://davidzhangzy.wordpress.com/2009/10/22/%e5%85%b3%e4%ba%8e%e5%9c%a8qtp10-0%e4%b8%ad%e4%bd%bf%e7%94%a8dom-html/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 21:17:41 +0000</pubDate>
		<dc:creator>davidzhangzy</dc:creator>
				<category><![CDATA[QuickTest Pro]]></category>
		<category><![CDATA[Software Testing]]></category>

		<guid isPermaLink="false">http://davidzhangzy.wordpress.com/?p=221</guid>
		<description><![CDATA[Dim divs Dim div Dim input set divs = Browser(&#8220;A&#8221;).Page(&#8220;b&#8221;).Frame(&#8220;c&#8221;).Object.getElementsByTagName(&#8220;Div&#8221;) input = Browser(&#8220;A&#8221;).Page(&#8220;b&#8221;).Frame(&#8220;c&#8221;).Object.createElement(&#8220;Input&#8221;) input.type = &#8220;radio&#8221; For each div in divs div.appendChild(input) Next<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=221&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Dim divs<br />
Dim div<br />
Dim input<br />
set divs = Browser(&#8220;A&#8221;).Page(&#8220;b&#8221;).Frame(&#8220;c&#8221;).Object.getElementsByTagName(&#8220;Div&#8221;)<br />
input = Browser(&#8220;A&#8221;).Page(&#8220;b&#8221;).Frame(&#8220;c&#8221;).Object.createElement(&#8220;Input&#8221;)<br />
input.type = &#8220;radio&#8221;<br />
For each div in divs<br />
div.appendChild(input)<br />
Next</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/davidzhangzy.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/davidzhangzy.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/davidzhangzy.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/davidzhangzy.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/davidzhangzy.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/davidzhangzy.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/davidzhangzy.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/davidzhangzy.wordpress.com/221/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=davidzhangzy.wordpress.com&amp;blog=8751802&amp;post=221&amp;subd=davidzhangzy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://davidzhangzy.wordpress.com/2009/10/22/%e5%85%b3%e4%ba%8e%e5%9c%a8qtp10-0%e4%b8%ad%e4%bd%bf%e7%94%a8dom-html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be77c1dafad95fe7174884ef42f0344f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">davidzhangzy</media:title>
		</media:content>
	</item>
	</channel>
</rss>
