<?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/"
	>

<channel>
	<title>Sphinx 中文站</title>
	<atom:link href="http://www.sphinxsearch.org/feed" rel="self" type="application/rss+xml" />
	<link>http://www.sphinxsearch.org</link>
	<description>简单高效的全文搜索引擎</description>
	<lastBuildDate>Tue, 15 May 2012 10:11:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Linux Bash Shell编程快速入门</title>
		<link>http://www.sphinxsearch.org/archives/414</link>
		<comments>http://www.sphinxsearch.org/archives/414#comments</comments>
		<pubDate>Tue, 15 May 2012 09:59:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=414</guid>
		<description><![CDATA[BASH 的基本语法 最简单的例子 —— Hello World! 关于输入、输出和错误输出 BASH 中对变量的规定（与 C 语言的异同） BASH 中的基本流程控制语法 函数的使用 2.1     最简单的例子 —— Hello World! 几乎所有的讲解编程的书给读者的第一个例子都是 Hello World 程序，那么我们今天也就从这个例子出发，来逐步了解 BASH。 用 vi 编辑器编辑一个 hello 文件如下： #!/bin/bash # This is a very simple example echo Hello World 这样最简单的一个 BASH 程序就编写完了。这里有几个问题需要说明一下： 一，第一行的 #! 是什么意思 二，第一行的 /bin/bash 又是什么意思 三，第二行是注释吗 四，echo 语句 五，如何执行该程序 #! 是说明 hello [...]]]></description>
			<content:encoded><![CDATA[<h1><span style="color: #000000;"><span style="color: #ff0000;">BASH 的基本语法</span></span></h1>
<ul>
<li><span style="color: #000000;">最简单的例子 —— Hello World!</span></li>
<li><span style="color: #000000;">关于输入、输出和错误输出</span></li>
<li><span style="color: #000000;">BASH 中对变量的规定（与 C 语言的异同）</span></li>
<li><span style="color: #000000;">BASH 中的基本流程控制语法</span></li>
<li><span style="color: #000000;">函数的使用</span></li>
</ul>
<h3><span style="color: #000000;">2.1     最简单的例子 —— Hello World!</span></h3>
<p><span style="color: #000000;">几乎所有的讲解编程的书给读者的第一个例子都是 Hello World 程序，那么我们今天也就从这个例子出发，来逐步了解 BASH。</span></p>
<p><span style="color: #000000;">用 vi 编辑器编辑一个 hello 文件如下：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash<br />
# This is a very simple example<br />
echo Hello World</strong></span></p>
<p><span style="color: #000000;">这样最简单的一个 BASH 程序就编写完了。这里有几个问题需要说明一下：</span></p>
<p><span style="color: #000000;">一，第一行的 #! 是什么意思<br />
二，第一行的 /bin/bash 又是什么意思<br />
三，第二行是注释吗<br />
四，echo 语句<br />
五，如何执行该程序</span></p>
<p><span style="color: #000000;">#! 是说明 hello 这个文件的类型的，有点类似于 Windows 系统下用不同文件后缀来表示不同文件类型的意思（但不相同）。Linux 系统根据 &#8220;#!&#8221; 及该字串后面的信息确定该文件的类型，关于这一问题同学们回去以后可以通过 &#8220;man magic&#8221;命令 及 /usr/share/magic 文件来了解这方面的更多内容。在 BASH 中 第一行的 &#8220;#!&#8221; 及后面的 &#8220;/bin/bash&#8221; 就表明该文件是一个 BASH 程序，需要由 /bin 目录下的 bash 程序来解释执行。BASH 这个程序一般是存放在 /bin 目录下，如果你的 Linux 系统比较特别，bash 也有可能被存放在 /sbin 、/usr/local/bin 、/usr/bin 、/usr/sbin 或 /usr/local/sbin 这样的目录下；如果还找不到，你可以用 &#8220;locate bash&#8221; &#8220;find / -name bash 2&gt; /dev/null&#8221; 或 &#8220;whereis bash&#8221; 这三个命令找出 bash 所在的位置；如果仍然找不到，那你可能需要自己动手安装一个 BASH 软件包了。</span></p>
<p><span style="color: #000000;">第二行的 &#8220;# This is a &#8230;&#8221; 就是 BASH 程序的注释，在 BASH 程序中从“#”号（注意：后面紧接着是“!”号的除外）开始到行尾的多有部分均被看作是程序的注释。的三行的 echo 语句的功能是把 echo 后面的字符串输出到标准输出中去。由于 echo 后跟的是 &#8220;Hello World&#8221; 这个字符串，因此 &#8220;Hello World&#8221;这个字串就被显示在控制台终端的屏幕上了。需要注意的是 BASH 中的绝大多数语句结尾处都没有分号。</span></p>
<p><span style="color: #000000;">如何执行该程序呢？有两种方法：一种是显式制定 BASH 去执行：</span></p>
<p><span style="color: #000000;"><strong>$ bash hello 或<br />
$ sh hello （这里 sh 是指向 bash 的一个链接，“lrwxrwxrwx 1 root root 4 Aug 20 05:41 /bin/sh -&gt; bash”）</strong></span></p>
<p><span style="color: #000000;">或者可以先将 hello 文件改为可以执行的文件，然后直接运行它，此时由于 hello 文件第一行的 &#8220;#! /bin/bash&#8221; 的作用，系统会自动用/bin/bash 程序去解释执行 hello 文件的：</span></p>
<p><span style="color: #000000;"><strong>$ chmod u+x hello<br />
$ ./hello</strong></span></p>
<p><span style="color: #000000;">此处没有直接 “$ hello”是因为当前目录不是当前用户可执行文件的默认目录，而将当前目录“.”设为默认目录是一个不安全的设置。</span></p>
<p><span style="color: #000000;">需要注意的是，BASH 程序被执行后，实际上 Linux 系统是另外开设了一个进程来运行的。</span></p>
<p><span style="color: #000000;"><br />
</span></p>
<h3><span style="color: #000000;">2.2     关于输入、输出和错误输出</span></h3>
<p><span style="color: #000000;"><em> </em>在字符终端环境中，标准输入/标准输出的概念很好理解。输入即指对一个应用程序 或命令的输入，无论是从键盘输入还是从别的文件输入；输出即指应用程序或命令产生的一些信息；与 Windows 系统下不同的是，Linux 系统下还有一个标准错误输出的概念，这个概念主要是为程序调试和系统维护目的而设置的，错误输出于标准输出分开可以让一些高级的错误信息不干扰正常的输出 信息，从而方便一般用户的使用。</span></p>
<p><span style="color: #000000;">在 Linux 系统中：标准输入(stdin)默认为键盘输入；标准输出(stdout)默认为屏幕输出；标准错误输出(stderr)默认也是输出到屏幕（上面的 std 表示 standard）。在 BASH 中使用这些概念时一般将标准输出表示为 1，将标准错误输出表示为 2。下面我们举例来说明如何使用他们，特别是标准输出和标准错误输出。</span></p>
<p><span style="color: #000000;">输入、输出及标准错误输出主要用于 I/O 的重定向，就是说需要改变他们的默认设置。先看这个例子：</span></p>
<p><span style="color: #000000;"><strong><span style="color: #0000ff;">$ ls &gt; ls_result</span><br />
<span style="color: #0000ff;">$ ls -l &gt;&gt; ls_result</span></strong></span></p>
<p><span style="color: #000000;">上面这两个命令分别将 ls 命令的结果<span style="color: #ff0000;">输出重定向到 ls_result 文件</span>中和<span style="color: #ff0000;">追加到 ls_result 文件中</span>，而不是输出到屏幕上。&#8221;&gt;&#8221;就是输出（标准输出和标准错误输出）重定向的代表符号，连续两个 &#8220;&gt;&#8221; 符号，即 &#8220;&gt;&gt;&#8221; 则表示不清除原来的而追加输出。下面再来看一个稍微复杂的例子：</span></p>
<p><span style="color: #0000ff;"><strong>$ find /home -name lost* 2&gt; err_result</strong></span></p>
<p><span style="color: #000000;">这个命令在 &#8220;&gt;&#8221; 符号之前多了一个 &#8220;2&#8243;，&#8221;2&gt;&#8221; 表示将标准错误输出重定向。由于 /home 目录下有些目录由于权限限制不能访问，因此会产生一些<span style="color: #ff0000;">标准错误输出被存放在 err_result 文件中</span>。大家可以设想一下 </span><span style="color: #000000;"><em>find /home -name lost* 2&gt;&gt;err_result</em> 命令会产生什么结果？</span></p>
<p><span style="color: #000000;">如果直接执行 <em>find /home -name lost* &gt; all_result</em> ，其结果是只有标准输出被存入 all_result 文件中，<span style="color: #3366ff;">要想让标准错误输出和标准输入一样都被存入到文件中</span>，那该怎么办呢？看下面这个例子：</span></p>
<p><span style="color: #0000ff;"><strong>$ find /home -name lost* &gt; all_result 2&gt;&amp; 1</strong></span></p>
<p><span style="color: #000000;">上面这个例子中将<span style="color: #ff0000;">首先将标准错误输出也重定向到标准输出中，再将标准输出重定向到 all_result 这个文件中。</span>这样我们就可以将所有的输出都存储到文件中了。为实现上述功能，还有一种简便的写法如下：</span></p>
<p><span style="color: #000000;"><strong>$ find /home -name lost* &gt;&amp; all_result</strong></span></p>
<p><span style="color: #000000;"><strong><br />
</strong></span></p>
<p><span style="color: #000000;">如果那些出错信息并不重要，下面这个命令可以让你<span style="color: #ff0000;">避开众多无用出错信息的干扰</span>：</span></p>
<p><span style="color: #000000;"><strong>$<span style="color: #0000ff;"> find /home -name lost* 2&gt; /dev/null</span></strong></span></p>
<p><span style="color: #000000;">同学们回去后还可以再试验一下如下几种重定向方式，看看会出什么结果，为什么？</span></p>
<p><span style="color: #000000;"><strong>$ find /home -name lost* &gt; all_result 1&gt;&amp; 2<br />
$ find /home -name lost* 2&gt; all_result 1&gt;&amp; 2<br />
$ find /home -name lost* 2&gt;&amp; 1 &gt; all_result</strong></span></p>
<p><span style="color: #000000;">另外一个非常有用的重定向操作符是 <span style="color: #ff0000;">&#8220;-&#8221;</span>，请看下面这个例子：</span></p>
<p><span style="color: #000000;"><strong>$ (cd /source/directory &amp;&amp; tar cf &#8211; . ) | (cd /dest/directory &amp;&amp; tar xvfp -)</strong></span></p>
<p><span style="color: #000000;">该命令表示把 /source/directory 目录下的所有文件通过压缩和解压，快速的全部移动到 /dest/directory 目录下去，这个命令在 /source/directory 和 /dest/directory 不处在同一个文件系统下时将显示出特别的优势。</span></p>
<p><span style="color: #000000;">下面还几种不常见的用法：</span></p>
<p><span style="color: #0000ff;"><strong><em>n&lt;&amp;- 表示将 n 号输入关闭<br />
&lt;&amp;- 表示关闭标准输入（键盘）<br />
n&gt;&amp;- 表示将 n 号输出关闭<br />
&gt;&amp;- 表示将标准输出关闭</em></strong></span></p>
<h3><span style="color: #000000;">2.3     BASH 中对变量的规定（与 C 语言的异同）</span></h3>
<p><span style="color: #000000;">好了下面我们进入正题，先看看 BASH 中的变量是如何定义和使用的。对于熟悉 C 语言的程序员，我们将解释 BASH 中的定义和用法与 C 语言中有何不同。</span></p>
<h4><span style="color: #000000;">2.3.1. BASH 中的变量介绍</span></h4>
<p><span style="color: #000000;">我们先来从整体上把握一下 BASH 中变量的用法，然后再去分析 BASH 中变量使用与 C 语言中的不同。<span style="color: #800000;">BASH 中的变量都是不能含有保留字，不能含有 &#8220;-&#8221; 等保留字符，也不能含有空格。</span></span></p>
<h4><span style="color: #000000;">2.3.1.1 简单变量</span></h4>
<p><span style="color: #000000;">在 BASH 中变量定义是不需要的，没有 &#8220;int i&#8221; 这样的定义过程。如果想用一个变量，只要他没有在前面被定义过，就直接可以用，当然你使用该变量的第一条语句应该是对他赋初值了，如果你不赋初值也没关 系，只不过该变量是空（ 注意：是 NULL，不是 0 ）。不给变量赋初值虽然语法上不反对，但不是一个好的编程习惯。好了我们看看下面的例子：</span></p>
<p><span style="color: #000000;">首先用 vi 编辑下面这个<a href="http://www.aka.org.cn/Lectures/002/Lecture-2.1.2/hello2">文件 hello2</a>：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash<br />
# give the initialize value to STR<br />
STR=&#8221;Hello World&#8221;<br />
echo $STR<br />
</strong><br />
在上面这个程序中我们需要注意下面几点：</span></p>
<p><span style="color: #000000;">一，变量赋值时，<span style="color: #800000;">&#8216;=&#8217;左右两边都不能有空格；</span><br />
二，BASH 中的语句结尾<span style="color: #800000;">不需要分号</span>（&#8221;;&#8221;）；<br />
三，除了在变量赋值和在FOR循环语句头中，BASH 中的<span style="color: #800000;">变量使用必须在变量前加&#8221;$&#8221;符号</span>，同学们可以将上面程序中第三行改为 &#8220;echo STR&#8221; 再试试，看看会出什么结果。==&gt;output: STR<br />
四，由于 BASH 程序是在一个新的进程中运行的，所以该程序中的变量定义和赋值不会改变其他进程或原始 Shell 中同名变量的值，也不会影响他们的运行。</span></p>
<p><span style="color: #000000;">更细致的文档甚至提到以但引号括起来的变量将不被 BASH 解释为变量，如 <span style="color: #ff0000;">&#8216;$STR&#8217; </span>，而被看成为纯粹的字符串。而且更为标准的变量引用方式是 ${STR} 这样的，<span style="color: #ff0000;">$STR 自不过是对 ${STR} 的一种简化</span>。在复杂情况下（即有可能产生歧义的地方）<strong><span style="color: #ff0000; font-size: medium;">最好用带 {} 的表示方式。</span></strong></span></p>
<p><span style="color: #000000;">BASH 中的变量既然不需要定义，也就<span style="color: #800000;">没有类型</span>一说，一个变量即可以被定义为一个字符串，也可以被再定义为整数。如果对该变量进行整数运算，他就被解释为整数；如果对他进行字符串操作，他就被看作为一个字符串。请看下面的例子：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash<br />
x=1999<br />
let &#8220;x = $x + 1&#8243;<br />
echo $x<br />
x=&#8221;olympic&#8217;&#8221;$x<br />
echo $x</strong></span></p>
<p><span style="color: #000000;">关于整数变量计算，有如下几种：&#8221; </span><span style="color: #000000;">+ &#8211; * / % &#8220;，他们的意思和字面意思相同。整数运算一般通过 let 和 expr 这两个指令来实现，如对变量 x 加 1 可以写作：</span><span style="color: #000000;">let <strong><span style="color: #ff0000; font-size: medium;">&#8220;</span></strong>x = $x + 1<span style="color: #ff0000;"><span style="font-size: medium;"><strong>&#8220;</strong></span> </span>或者 </span><span style="color: #000000;">x=<strong><span style="color: #ff0000; font-size: medium;">`</span></strong>expr $x + 1<span style="font-size: medium;"><strong><span style="color: #ff0000;">`</span></strong></span></span></p>
<p><span style="color: #000000;">在比较操作上，整数变量和字符串变量各不相同，详见下表：</span></p>
<div>
<table border="1" width="75%">
<tbody>
<tr>
<td width="26%">
<div><span style="color: #000000;">对应的操作</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">整数操作</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">字符串操作</span></div>
</td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">相同</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">-eq</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">=</span></div>
</td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">不同</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">-ne</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">!=</span></div>
</td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">大于</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">-gt</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">&gt;</span></div>
</td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">小于</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">-lt</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">&lt;</span></div>
</td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">大于或等于</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">-ge</span></div>
</td>
<td width="37%"><span style="color: #000000;"><br />
</span></td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">小于或等于</span></div>
</td>
<td width="37%">
<div><span style="color: #000000;">-le</span></div>
</td>
<td width="37%"><span style="color: #000000;"><br />
</span></td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">为空</span></div>
</td>
<td width="37%"><span style="color: #000000;"><br />
</span></td>
<td width="37%">
<div><span style="color: #000000;">-z</span></div>
</td>
</tr>
<tr>
<td width="26%">
<div><span style="color: #000000;">不为空</span></div>
</td>
<td width="37%"><span style="color: #000000;"><br />
</span></td>
<td width="37%">
<div><span style="color: #000000;">-n</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<p><span style="color: #000000;"><br />
比如：</span></p>
<p><span style="color: #000000;">比较字符串 a 和 b 是否相等就写作：</span><span style="color: #000000;"><span style="color: #0000ff;">if [ $a = $b ]</span><br />
判断字符串 a 是否为空就写作：<span style="color: #0000ff;"> </span></span><span style="color: #000000;"><span style="color: #0000ff;">if [ -z $a ]</span><br />
判断整数变量 a 是否大于 b 就写作：</span><span style="color: #0000ff;">if [ $a -gt $b ]</span></p>
<p><span style="color: #000000;">更细致的文档推荐在字符串比较时尽量不要使用 -n ，而用 ! -z 来代替。（其中符号 &#8220;!&#8221; 表示求反操作）</span></p>
<p><span style="color: #000000;">BASH 中的变量除了用于对 整数 和 字符串 进行操作以外，另一个作用是作为文件变量。BASH 是 Linux 操作系统的 Shell，因此系统的文件必然是 BASH 需要操作的重要对象，如 </span><span style="color: #000000;">if [ -x /root ] 可以用于判断 /root 目录是否可以被当前用户进入。下表列出了 BASH 中用于判断文件属性的操作符：</span></p>
<div>
<table border="1" width="50%">
<tbody>
<tr>
<td width="27%">
<div><span style="color: #000000;">运算符</span></div>
</td>
<td width="73%"><span style="color: #000000;">含义（ 满足下面要求时返回 TRUE ）</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-e file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 已经存在</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-f file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 是普通文件</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-s file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 大小不为零</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-d file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 是一个目录</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-r file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 对当前用户可以读取</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-w file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 对当前用户可以写入</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-x file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 对当前用户可以执行</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-g file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 的 GID 标志被设置</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-u file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 的 UID 标志被设置</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-O file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 是属于当前用户的</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">-G file</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file 的组 ID 和当前用户相同</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">file1 -nt file2</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file1 比 file2 更新</span></td>
</tr>
<tr>
<td width="27%">
<div><span style="color: #000000;">file1 -ot file2</span></div>
</td>
<td width="73%"><span style="color: #000000;">文件 file1 比 file2 更老</span></td>
</tr>
</tbody>
</table>
</div>
<p><span style="color: #000000;"><br />
注意：上表中的 file 及 file1、file2 都是指某个文件或目录的<span style="color: #ff0000;">路径</span>。</span></p>
<h4><span style="color: #000000;">2.3.1.1. 关于局部变量</span></h4>
<p><span style="color: #000000;">在 BASH 程序中如果一个变量被使用了，那么直到该程序的结尾，该变量都一直有效。为了使得某个变量存在于一个局部程序块中，就引入了局部变量的概念。BASH 中，在变量首次被赋初值时加上 local 关键字就可以声明一个局部变量，如下面这个例子：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash<br />
HELLO=Hello<br />
function hello {<br />
local HELLO=World<br />
echo $HELLO<br />
}<br />
echo $HELLO<br />
hello<br />
echo $HELLO</strong></span></p>
<p><span style="color: #000000;">该程序的执行结果是：</span></p>
<p><span style="color: #000000;"><strong>Hello<br />
World<br />
Hello</strong></span></p>
<p><span style="color: #000000;">这个执行结果表明全局变量 $HELLO 的值在执行函数 hello 时并没有被改变。也就是说<span style="color: #800000;">局部变量</span> $HELLO 的<span style="color: #800000;">影响</span>只存在于函数那个<span style="color: #800000;">程序块</span>中。</span></p>
<h4><span style="color: #000000;">2.3.2. BASH 中的变量与 C 语言中变量的区别</span></h4>
<p><span style="color: #000000;">这里我们为原来不熟悉 BASH 编程，但是非常熟悉 C 语言的程序员总结一下在 BASH 环境中使用变量需要注意的问题。</span></p>
<p><span style="color: #000000;">1，BASH 中的变量在引用时都需要在变量前加上 &#8220;$&#8221; 符号（ 第一次赋值及在For循环的头部不用加 &#8220;$&#8221;符号 ）；<br />
2，<span style="color: #800000;">BASH 中没有浮点运算</span>，因此也就没有浮点类型的变量可用；<br />
3，BASH 中的整形变量的比较符号与 C 语言中完全不同，而且<span style="color: #800000;">整形变量的算术运算也需要经过 let 或 expr 语句来处理；</span></span></p>
<h3><span style="color: #000000;">2.4     BASH 中的基本流程控制语法</span></h3>
<p><span style="color: #000000;">BASH 中几乎含有 C 语言中常用的所有控制结构，如条件分支、循环等，下面逐一介绍。</span></p>
<h4><span style="color: #000000;">2.4.1 if&#8230;then&#8230;else</span></h4>
<p><span style="color: #000000;">if 语句用于判断和分支，其语法规则和 C 语言的 if 非常相似。其几种基本结构为：</span></p>
<p><span style="color: #000000;"><strong><em>if [ expression ]<br />
then<br />
statments<br />
fi</em></strong></span></p>
<p><span style="color: #000000;">或者</span></p>
<p><span style="color: #000000;"><strong><em>if [ expression ]<br />
then<br />
statments<br />
else<br />
statments<br />
fi</em></strong></span></p>
<p><span style="color: #000000;">或者</span></p>
<p><span style="color: #000000;"><strong><em>if [ expression ]<br />
then<br />
statments<br />
else if [ expression ]<br />
then<br />
statments<br />
else<br />
statments<br />
fi</em></strong></span></p>
<p><span style="color: #000000;">或者</span></p>
<p><span style="color: #000000;"><strong><em>if [ expression ]<br />
then<br />
statments<br />
elif [ expression ]<br />
then<br />
statments<br />
else<br />
statments<br />
fi</em></strong></span></p>
<p><span style="color: #000000;">值得说明的是如果你将 if 和 then 简洁的写在一行里面，就必须在 then 前面加上分号，如：</span><span style="color: #000000;">if [ expression ]; then &#8230; 。下面这个例子说明了如何使用 if 条件判断语句：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>if [ $1 -gt 90 ]<br />
then<br />
echo &#8220;Good, $1&#8243;<br />
elif [ $1 -gt 70 ]<br />
then<br />
echo &#8220;OK, $1&#8243;<br />
else<br />
echo &#8220;Bad, $1&#8243;<br />
fi</strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>exit 0</strong></p>
<p><span style="color: #000000;">上面例子中的 $1 是指命令行的第一个参数，这个会在后面的“BASH 中的特殊保留字”中讲解。</span></p>
<h4><span style="color: #000000;">2.4.2 for</span></h4>
<p><span style="color: #000000;">for 循环结构与 C 语言中有所不同，在 BASH 中 for 循环的基本结构是：</span></p>
<p><span style="color: #000000;"><strong><em>for $var in</em></strong></span></p>
<ul>
<li>
<ul>
<li>
<ul>
<li>
<ul>
<li>
<ul>
<li>保留变量</li>
<li>随机数</li>
<li>运算符</li>
<li>变量的特殊操作</li>
</ul>
<ul>
<li><span style="color: #000000;">BASH 中对返回值的处理</span></li>
<li><span style="color: #000000;">用 BASH 设计简单用户界面</span></li>
<li><span style="color: #000000;">在 BASH 中读取用户输入</span></li>
<li><span style="color: #000000;">一些特殊的惯用法</span></li>
<li><span style="color: #000000;">BASH 程序的调试</span></li>
<li><span style="color: #000000;">关于 BASH2</span></li>
</ul>
<ul>
<li>
<ul><span style="color: #000000;">中的所有项加上数字列在屏幕上等待用户选择，在用户作出选择后，变量 $var 中就包含了那个被选中的字符串，然后就可以对该变量进行需要的操作了。我们可以从下面的<a href="http://www.aka.org.cn/Lectures/002/Lecture-2.1.2/select">例子</a>中更直观的来理解这个功能：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>OPTIONS=&#8221;Hello Quit&#8221;<br />
select opt in $OPTIONS; do<br />
if [ "$opt" = "Quit" ]; then<br />
echo done<br />
exit<br />
elif [ "$opt" = "Hello" ]; then<br />
echo Hello World<br />
else<br />
clear<br />
echo bad option<br />
fi<br />
done</strong></p>
<p><strong> </strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">大家可以试着执行上面的程序，看看是什么执行结果。</span></p>
<h3><span style="color: #000000;">4.3     在 BASH 中读取用户输入</span></h3>
<p><span style="color: #000000;">BASH 中通过 read 函数来实现读取用户输入的功能，如下面这段程序：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>echo Please enter your name<br />
read NAME<br />
echo &#8220;Hi! $NAME !&#8221;</strong></p>
<p><strong> </strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">上面这个脚本读取用户的输入，并回显在屏幕上。</span></p>
<p><span style="color: #000000;">另外 BASH 中还提供另外一种称为 <span style="color: #800000;">here documents 的结构????</span>，可以将用户需要通过键盘输入的字符串改为从程序体中直接读入，如密码。下面的<a href="http://www.aka.org.cn/Lectures/002/Lecture-2.1.2/here">小程序</a>演示了这个功能：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>passwd=&#8221;aka@tsinghua&#8221;<br />
ftp -n localhost &lt;&lt;FTPFTP<br />
user anonymous $passwd<br />
binary<br />
bye<br />
FTPFTP</strong></p>
<p><strong> </strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">这个程序在用户需要通过键盘敲入一些字符时，通过程序内部的动作来模拟键盘输入。请注意 here documents 的基本结构为：</span></p>
<p><span style="color: #000000;"><strong><em>command &lt;&lt;SOMESPECIALSTRING<br />
statments<br />
&#8230;<br />
SOMESPECIALSTRING</em></strong></span></p>
<p><span style="color: #000000;">这里要求在需要键盘输入的命令后，直接加上 &lt;&lt;符号，然后跟上一个特别的字符串，在该串后按顺序输入本来应该由键盘输入的所有字符，在所有需要输入的字符都结束后，重复一遍前面 &lt;&lt;符号后的“特别的字符串”即表示该输入到此结束。</span></p>
<h3><span style="color: #000000;">4.4 一些特殊的惯用法</span></h3>
<p><span style="color: #000000;">在 BASH 中 () 一对括号一般被用于求取括号中表达式的值或命令的执行结果，如：(a=hello; echo $a) ，其作用相当于 `&#8230;` 。</span></p>
<p><span style="color: #000000;">: 有两个含义，一是表示空语句，有点类似于 C 语言中的单个 &#8220;;&#8221; 。表示该行是一个空命令，如果被用在 while/until 的头结构中，则表示值 0，会使循环一直进行下去，如下例：</span></p>
<p><span style="color: #000000;"><strong><em>while :<br />
do<br />
operation-1<br />
operation-2<br />
&#8230;<br />
operation-n<br />
done</em></strong></span></p>
<p><span style="color: #000000;">另外 : 还可以用于求取后面变量的值，比如：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>: ${HOSTNAME?} {USER?} {MAIL?}<br />
echo $HOSTNAME<br />
echo $USER<br />
echo $MAIL</strong></p>
<p><strong> </strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">在 BASH 中 export 命令用于将系统变量输出到外层的 Shell 中了。</span></p>
<h3><span style="color: #000000;">4.5 BASH 程序的调试</span></h3>
<p><span style="color: #000000;">用 </span><span style="color: #000000;">bash -x bash-script 命令，可以查看一个出错的 BASH 脚本到底错在什么地方，可以帮助程序员找出脚本中的错误。</span></p>
<p><span style="color: #000000;">另外用 trap 语句可以在 BASH 脚本出错退出时打印出一些变量的值，以供程序员检查。trap 语句必须作为继 &#8220;#!/bin/bash&#8221; 后的第一句非注释代码，一般 trap 命令被写作： </span><span style="color: #000000;">trap &#8216;message $checkvar1 $checkvar2&#8242; EXIT 。</span></p>
<h3><span style="color: #000000;">4.6 关于 BASH2</span></h3>
<p><span style="color: #000000;">使用 bash -version 命令可以看出当前你正在使用的 BASH 是什么版本，一般版本号为1.14或其他版本。而现在机器上一般还安装了一个版本号为 2.0 的 BASH 。该 BASH 也在 /bin 目录下。BASH2 提供了一些新功能，有兴趣的同叙可以自己去看相关资料，或直接 man bash2 即可。</span></ul>
</li>
<p><span style="color: #000000;"><strong><em><br />
do<br />
statments use $var<br />
done</em></strong></span></p>
<p><span style="color: #000000;">上面的语法结构在执行后，BASH 会将</span></ul>
</li>
<p><span style="color: #000000;">部分，则 day 将取遍命令行的所有参数。如<a href="http://www.aka.org.cn/Lectures/002/Lecture-2.1.2/for2">这个程序</a>：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>for param<br />
do<br />
echo $param<br />
done</strong></p>
<p><strong> </strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">上面这个程序将列出所有命令行参数。for 循环结构的循环体被包含在 do/done 对中，这也是后面的 while、until 循环所具有的特点。</span></p>
<h4><span style="color: #000000;">2.4.3 while</span></h4>
<p><span style="color: #000000;">while 循环的基本结构是：</span></p>
<p><span style="color: #000000;"><strong><em>while [ condition ]<br />
do<br />
statments<br />
done</em></strong></span></p>
<p><span style="color: #000000;">这个结构请大家自己编写一个例子来验证。</span></p>
<h4><span style="color: #000000;">2.4.4 until</span></h4>
<p><span style="color: #000000;">until 循环的基本结构是：</span></p>
<p><span style="color: #000000;"><strong><em>until [ condition is TRUE ]<br />
do<br />
statments<br />
done</em></strong></span></p>
<p><span style="color: #000000;">这个结构也请大家自己编写一个例子来验证。</span></p>
<h4><span style="color: #000000;">2.4.5 case</span></h4>
<p><span style="color: #000000;">BASH 中的 case 结构与 C 语言中的 switch 语句的功能比较类似，可以用于进行多项分支控制。其基本结构是：</span></p>
<p><span style="color: #000000;"><strong><em>case &#8220;$var&#8221; in<br />
condition1 )<br />
statments1;;<br />
condition2 )<br />
statments2;;<br />
&#8230;<br />
* )<br />
default statments;;<br />
esac</em></strong></span></p>
<p><span style="color: #000000;">下面这个程序是运用 case 结构进行分支执行的<a href="http://www.aka.org.cn/Lectures/002/Lecture-2.1.2/case">例子</a>：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>echo &#8220;Hit a key, then hit return.&#8221;<br />
read Keypress</strong></p>
<p><strong>case &#8220;$Keypress&#8221; in<br />
[a-z] ) echo &#8220;Lowercase letter&#8221;;;<br />
[A-Z] ) echo &#8220;Uppercase letter&#8221;;;<br />
[0-9] ) echo &#8220;Digit&#8221;;;<br />
* ) echo &#8220;Punctuation, whitespace, or other&#8221;;;<br />
esac</p>
<p></strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">上面例子中的第四行 &#8220;read Keypress&#8221; 一句中的 read 语句表示从键盘上读取输入。这个命令将在本讲义的 BASH 的其他高级问题中讲解。</span></p>
<h4><span style="color: #000000;">2.4.6 break/continue</span></h4>
<p><span style="color: #000000;">熟悉 C 语言编程的都很熟悉 break 语句和 continue 语句。BASH 中同样有这两条语句，而且作用和用法也和 C 语言中相同，break 语句可以让程序流程从当前循环体中完全跳出，而 continue 语句可以跳过当次循环的剩余部分并直接进入下一次循环。</span></p>
<h3><span style="color: #000000;">2.5     函数的使用</span></h3>
<p><span style="color: #000000;">BASH 是一个相对简单的脚本语言，不过为了方便结构化的设计，BASH 中也提供了函数定义的功能。BASH 中的函数定义很简单，只要向下面这样写就可以了：</span></p>
<p><span style="color: #000000;"><strong><em>function my_funcname {<br />
code block<br />
}</em></strong></span></p>
<p><span style="color: #000000;">或者</span></p>
<p><span style="color: #000000;"><strong><em>my_funcname() {<br />
code block<br />
}</em></strong></span></p>
<p><span style="color: #000000;">上面的第二种写法更接近于 C 语言中的写法。BASH 中要求函数的定义必须在函数使用之前，这是和 C 语言用头文件说明函数方法的不同。</span></p>
<p><span style="color: #000000;">更进一步的问题是如何给函数传递参数和获得返回值。BASH 中函数参数的定义并不需要在函数定义处就制定，而只需要在函数被调用时用 BASH 的保留变量 $1 $2 &#8230; 来引用就可以了；BASH 的返回值可以用 return 语句来指定返回一个特定的整数，如果没有 return 语句显式的返回一个返回值，则返回值就是该函数最后一条语句执行的结果（一般为 0，如果执行失败返回错误码）。函数的返回值在调用该函数的程序体中通过 $? 保留字来获得。下面我们就来看一个用函数来计算整数平方的例子：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>square() {<br />
let &#8220;res = $1 * $1&#8243;<br />
return $res<br />
}</strong></p>
<p><strong>square $1<br />
result=$?<br />
echo $result</p>
<p></strong><strong> </strong><strong>exit 0</strong></p>
<h1><span style="color: #ff0000;"><br />
BASH 中的特殊保留字</span></h1>
<h3>3.1     保留变量</h3>
<p>BASH 中有一些保留变量，下面列出了一些：</p>
<p>$IFS　　这个变量中保存了用于分割输入参数的分割字符，默认识空格。<br />
$HOME 　这个变量中存储了当前用户的根目录路径。<br />
$PATH 　这个变量中存储了当前 Shell 的默认路径字符串。<br />
$PS1　　表示第一个系统提示符。<br />
$PS2　　表示的二个系统提示符。<br />
$PWD　　表示当前工作路径。<br />
$EDITOR 表示系统的默认编辑器名称。<br />
$BASH 　表示当前 Shell 的路径字符串。<br />
$0, $1, $2, &#8230;<br />
表示系统传给脚本程序或脚本程序传给函数的第0个、第一个、第二个等参数。<br />
$#　　　表示脚本程序的命令参数个数或函数的参数个数。<br />
$$　　　表示该脚本程序的进程号，常用于生成文件名唯一的临时文件。<br />
$?　　　表示脚本程序或函数的返回状态值，正常为 0，否则为非零的错误号。<br />
$*　　　表示所有的脚本参数或函数参数。<br />
$@　　　和 $* 涵义相似，但是比 $* 更安全。<br />
$!　　　表示最近一个在后台运行的进程的进程号。</p>
<h3>3.2    <span style="color: #000000;">随机数</span></h3>
<p><span style="color: #000000;">随机数是经常要用到的，BASH 中也提供了这个功能，请看下面这个程序：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong># Prints different random integer from 1 to 65536</strong></p>
<p><strong>a=<span style="color: #0000ff;">$RANDOM </span><br />
echo $a</p>
<p></strong><strong> </strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">这个程序可以在每次执行的时候随机的打印出一个大小在 <span style="color: #0000ff;">1 到 65536</span> 之间的整数。</span></p>
<h3><span style="color: #000000;">3.3     运算符</span></h3>
<p><span style="color: #000000;">算术运算符<br />
+ &#8211; * / % 表示加减乘除和取余运算<br />
+= -= *= /= 同 C 语言中的含义</span></p>
<p><span style="color: #000000;">位操作符<br />
&lt;&lt; &lt;&lt;= &gt;&gt; &gt;&gt;= 表示位左右移一位操作<br />
&amp; &amp;= | |= 表示按位与、位或操作<br />
~ ! 表示非操作<br />
^ ^= 表示异或操作</span></p>
<p><span style="color: #000000;">关系运算符<br />
&lt; &gt; &lt;= &gt;= == != 表示大于、小于、大于等于、小于等于、等于、不等于操作<br />
&amp;&amp; || 逻辑与、逻辑或操作</span></p>
<h3><span style="color: #000000;">3.4     变量的特殊操作</span></h3>
<p><span style="color: #000000;">BASH 中还有一些对变量的简洁、快速的操作，大家还记得 &#8220;${var}&#8221; 和 &#8220;$var&#8221; 同样是对变量的引用吧，对 ${var} 进行一些变化就可以产生一些新功能：<br />
${var-default} 表示如果变量 $var 还没有设置，则保持 $var 没有设置的状态，并返回后面的默认值 default。<br />
${var=default} 表示如果变量 $var 还没有设置，则取后面的默认值 default。<br />
${var+otherwise} 表示如果变量 $var 已经设置，则返回 otherwise 的值，否则返回空( null )。<br />
${var?err_msg} 表示如果变量 $var 已经设置，则返回该变量的值，否则将后面的 err_msg 输出到标准错误输出上。</span></p>
<p><span style="color: #000000;">请同学们自己尝试下面的例子：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>echo ${var?There is an error}</strong></p>
<p><strong> </strong><strong></strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">还有下面一些用法，这些用法主要用于从文件路径字符串中提取有用信息：<br />
${var#pattern}, ${var##pattern} 用于从变量 $var 中剥去最短（最长）的和 pattern 相匹配的最左侧的串。<br />
${var%pattern}, ${var%%pattern} 用于从变量 $var 中剥去最短（最长）的和 pattern 相匹配的最右侧的串。</span></p>
<p><span style="color: #000000;">另外 BASH  中还加入下面一些操作：<br />
${var:pos} 表示去掉变量 $var 中前 pos 个字符。<br />
${var:pos:len} 表示变量 $var 中去掉前 pos 个字符后的剩余字符串的前 len 个字符。<br />
${var/pattern/replacement} 表示将变量 $var 中第一个出现的 pattern 模式替换为 replacement 字符串。<br />
${var//pattern/replacement} 表示将变量 $var 中出现的所有 pattern 模式全部都替换为 replacment 字符串。</span></p>
<h1><span style="color: #ff0000;"><br />
BASH 中的其他高级问题</span></h1>
<h3><span style="color: #000000;">4.1     BASH 中对返回值的处理</span></h3>
<p><span style="color: #000000;">无论是在 Shell 中对 BASH 脚本返回值的处理，还是在脚本中对函数返回值的处理，都是通过 &#8220;$?&#8221; 系统变量来获得。BASH 要求返回值必须为一个整数，不能用 return 语句返回字符串变量。</span></p>
<p><span style="color: #000000;"><br />
</span></p>
<h3><span style="color: #000000;">4.2     用 BASH 设计简单用户界面</span></h3>
<p><span style="color: #000000;"><em> </em>BASH 中提供了一个小的语句格式，可以让程序快速的设计出一个字符界面的用户交互选择的菜单，该功能就是由 select 语句来实现的，select 语句的语法为：</span></p>
<p><span style="color: #000000;"><strong><em>select var in</em></strong></span></ul>
</li>
<p><span style="color: #000000;">; do 。下面是一个运用 for 进行循环的例子：</span></p>
<p><span style="color: #000000;"><strong>#!/bin/bash</strong></span></p>
<p><strong>for day in Sun Mon Tue Wed Thu Fri Sat<br />
do<br />
echo $day<br />
done</strong></p>
<p><strong># 如果列表被包含在一对双引号中，则被认为是一个元素<br />
for day in &#8220;Sun Mon Tue Wed Thu Fri Sat&#8221;<br />
do<br />
echo $day<br />
done</p>
<p></strong><strong></strong><strong>exit 0</strong></p>
<p><span style="color: #000000;">注意上面的例子中，在 for 所在那行的变量 day 是没有加 &#8220;$&#8221; 符号的，而在循环体内，echo 所在行变量 $day 是必须加上 &#8220;$&#8221; 符号的。另外如果写成 for day 而没有后面的 in</span></ul>
</li>
<p><span style="color: #000000;">是 $var 需要遍历的一个集合，do/done 对包含了循环体，相当于 C 语言中的一对大括号。另外如果do 和 for 被写在同一行，必须在 do 前面加上 &#8220;;&#8221;。如： </span><span style="color: #000000;">for $var in</span></ul>
</li>
<p><span style="color: #000000;"><strong><em><br />
do<br />
statments<br />
done</em></strong></span></p>
<p><span style="color: #000000;">其中 $var 是循环控制变量，</span></ul>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/414/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>hp cq45笔记本添加新硬盘ghost安装win7 记录</title>
		<link>http://www.sphinxsearch.org/archives/393</link>
		<comments>http://www.sphinxsearch.org/archives/393#comments</comments>
		<pubDate>Tue, 15 May 2012 04:01:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[windows 7]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=393</guid>
		<description><![CDATA[新买了一希捷320G硬盘，预做win7系统。在光驱不能使用的情况下，使用一下步骤完成安装： 1、新硬盘先在windows xp下分4个区。其中C盘为主分区和活动分区（这个一定要，否则笔记本不能识别） 2、在xp系统下，下载win 7 ghost版本，解压。解压出win7.gho到windows xp下的任一分区，如D盘里 3、使用硬盘ghost把win7.gho ghost到 新硬盘 C盘里 4、把新硬盘安装回笔记本里，开机自动安装]]></description>
			<content:encoded><![CDATA[<p>新买了一希捷320G硬盘，预做win7系统。在光驱不能使用的情况下，使用一下步骤完成安装：</p>
<p>1、新硬盘先在windows xp下分4个区。其中C盘为主分区和活动分区（这个一定要，否则笔记本不能识别）<br />
2、在xp系统下，下载win 7 ghost版本，解压。解压出win7.gho到windows xp下的任一分区，如D盘里<br />
3、使用硬盘ghost把win7.gho ghost到 新硬盘 C盘里</p>
<p>4、把新硬盘安装回笔记本里，开机自动安装</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/393/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vi/vim 跳转到指定行</title>
		<link>http://www.sphinxsearch.org/archives/404</link>
		<comments>http://www.sphinxsearch.org/archives/404#comments</comments>
		<pubDate>Tue, 08 May 2012 10:36:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=404</guid>
		<description><![CDATA[vi/vim 跳转到指定行]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">（1）</div>
<div id="_mcePaste">按ESC,然后123gg</div>
<div id="_mcePaste">就是跳到123行</div>
<div id="_mcePaste">(2)</div>
<div id="_mcePaste">输入 ：行号</div>
<div id="_mcePaste">就跳到你要的行了！</div>
<div>###############################</div>
<div>
<p><span style="font-size: medium;"><span style="color: #ff0000;">添加、删除注释：</span></span><br style="color: #9a9a9a; font-family: arial; font-size: 12px; line-height: 18px;" /><span style="color: #000000;"><br style="color: #9a9a9a; font-family: arial; font-size: 12px; line-height: 18px;" /><span style="font-size: small;">注释：ctrl+v 进入列编辑模式,向下或向上移动光标,</span><span style="font-size: 12px; line-height: 18px;">把需要注释的行的开头标记起来,然后按大写的I,再插入注释符,比如&#8221;//&#8221;,再按Esc,就会全部注释了。</span><br style="color: #9a9a9a; font-family: arial; font-size: 12px; line-height: 18px;" /><br style="color: #9a9a9a; font-family: arial; font-size: 12px; line-height: 18px;" /></span></p>
<div style="word-wrap: break-word; font-size: 12px; line-height: 18px;" dir="ltr"><span style="color: #000000;"><span style="font-size: small;">删除：先按v,进入visual模式,横向选中列的个数(如&#8221;/</span> <span style="font-size: small;">/&#8221;注释符号,需要选中两列),再按Esc,再按ctrl+v 进入列编辑模式,向下或向上移动光标,选中注释部分,然后按d,</span> <span style="font-size: small;">就会删除注释符号。<br />
</span><br />
<span style="font-size: medium;">使用替换命令：</p>
<p><span style="font-size: small;">:%s/^/\/\//g来在全部内容的行首添加//号注释<br />
:2,50s/^/\/\//g在2~50行首添加//号注释<br />
反过来替换既是删除操作。</span></p>
<p></span></span></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/404/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php file_get_contents 出现HTTP request failed! HTTP/1.1 505 HTTP Version Not Supported error</title>
		<link>http://www.sphinxsearch.org/archives/391</link>
		<comments>http://www.sphinxsearch.org/archives/391#comments</comments>
		<pubDate>Fri, 04 May 2012 07:27:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=391</guid>
		<description><![CDATA[在做一个接口的时候，使用file_get_contents出现 HTTP request failed! HTTP/1.1 505 HTTP Version Not Supported error。查了一下手册， Note: 如果要打开有特殊字符的 URL （比如说有空格），就需要使用 urlencode() 进行 URL 编码。 切记，对中文一定要进行先编码后使用]]></description>
			<content:encoded><![CDATA[<p>在做一个接口的时候，使用file_get_contents出现 HTTP request failed! HTTP/1.1 505 HTTP Version Not Supported error。查了一下手册，</p>
<p><span style="color: #ff0000;">Note: 如果要打开有特殊字符的 URL （比如说有空格），就需要使用 urlencode() 进行 URL 编码。 </span></p>
<p>切记，对中文一定要进行先编码后使用</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/391/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于input checkbox 选中，全选的一个问题——js小札记</title>
		<link>http://www.sphinxsearch.org/archives/388</link>
		<comments>http://www.sphinxsearch.org/archives/388#comments</comments>
		<pubDate>Thu, 19 Apr 2012 03:17:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[lamp]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=388</guid>
		<description><![CDATA[jquery在判断input 复选框选中状态的时候，发现不能直接使用 $(&#8216;input&#8217;).attr(&#8216;checked&#8217;)。在chrome中，这样不管选择不选择 alert()出来的都是undefined。试过多次后，有两种途径实现： 1、还是用原生态的js进行测试：this.checked，这样就实现了当前checkbox是否选中的状态。 2、$(&#8216;input:checkbox&#8217;).is(&#8216;:checked&#8217;):    这里会alert出 true/flase]]></description>
			<content:encoded><![CDATA[<p>jquery在判断input 复选框选中状态的时候，发现不能直接使用 $(&#8216;input&#8217;).attr(&#8216;checked&#8217;)。在chrome中，这样不管选择不选择 alert()出来的都是undefined。试过多次后，有两种途径实现：</p>
<p>1、还是用原生态的js进行测试：this.checked，这样就实现了当前checkbox是否选中的状态。</p>
<p>2、$(&#8216;input:checkbox&#8217;).is(&#8216;:checked&#8217;):    这里会alert出 true/flase</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/388/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PureFTP安装配置</title>
		<link>http://www.sphinxsearch.org/archives/382</link>
		<comments>http://www.sphinxsearch.org/archives/382#comments</comments>
		<pubDate>Fri, 02 Mar 2012 17:00:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=382</guid>
		<description><![CDATA[PureFTP+Mysql验证 FTP的原理 21端口开放，用于连接。20端口用于传输数据！ 匿名用户 anonymous 主动模式和被动模式 主动模式是客户端主动，例如用1030端口连接21，再开放1031和20端口传输数据，但是如果有防火墙的话，无法主动传输，服务器会打开大于1024端口并且通过客户端进行连接 tar -xjvf pure-ftpd-1.0.22.tar.bz2 ./configure &#8211;prefix=/usr/local/pureftpd &#8211;with-mysql=/usr/local/mysql &#8211;with-paranoidmsg &#8211;with-shadow &#8211;with-welcomemsg &#8211;with-uploadscript &#8211;with-quotas &#8211;with-cookie &#8211;with-virtualhosts &#8211;with-virtualroot &#8211;with-diraliases &#8211;with-sysquotas &#8211;with-ratios &#8211;with-ftpwho &#8211;with-throttling &#8211;with-language=simplified-chinese &#8211;with-mysql=/usr/local/mysql \ 此处的 /usr/local/mysql 请改为你的mysql实际安装路径.如果出现类似configure: error: Your MySQL client libraries aren&#8217;t properly installed 的错误,请将mysql目录下的 include/mysql下的mysql.h文件以及lib/mysql下的全部文件,连接(直接复制过去或许也可)到 /usr/lib 目录下（参考） cp /usr/local/mysql/lib/libmysqlclent* /usr/lib(真正解决办法) ##运行 ldconfig，加载所有共享链接库 cp -a ftp /var/www/html/pureftp make &#38;&#38; [...]]]></description>
			<content:encoded><![CDATA[<p>PureFTP+Mysql验证</p>
<p><strong>FTP</strong><strong>的原理</strong><strong> </strong></p>
<p><strong>21</strong><strong>端口开放，用于连接。</strong><strong>20</strong><strong>端口用于传输数据！</strong><strong> </strong></p>
<p><strong>匿名用户</strong><strong> </strong></p>
<p><strong>anonymous</strong></p>
<p><strong>主动模式和被动模式</strong><strong> </strong></p>
<p><strong>主动模式是客户端主动，例如用</strong><strong>1030</strong><strong>端口连接</strong><strong>21</strong><strong>，再开放</strong><strong>1031</strong><strong>和</strong><strong>20</strong><strong>端口传输数据，但是如果有防火墙的话，无法主动传输，服务器会打开大于</strong><strong>1024</strong><strong>端口并且通过客户端进行连接</strong></p>
<p><strong><strong>tar -xjvf  pure-ftpd-1.0.22.tar.bz2</strong></strong></p>
<p><strong><strong>./configure &#8211;prefix=/usr/local/pureftpd  &#8211;with-mysql=/usr/local/mysql &#8211;with-paranoidmsg &#8211;with-shadow &#8211;with-welcomemsg  &#8211;with-uploadscript &#8211;with-quotas &#8211;with-cookie &#8211;with-virtualhosts  &#8211;with-virtualroot &#8211;with-diraliases &#8211;with-sysquotas &#8211;with-ratios  &#8211;with-ftpwho &#8211;with-throttling  &#8211;with-language=simplified-chinese</strong></strong></p>
<p><strong>&#8211;with-mysql=/usr/local/mysql \ 此处的 /usr/local/mysql  请改为你的mysql实际安装路径.如果出现类似configure:  error: Your MySQL client libraries aren&#8217;t properly installed 的错误,请将mysql目录下的  include/mysql下的mysql.h文件以及lib/mysql下的全部文件,连接(直接复制过去或许也可)到 /usr/lib 目录下（参考）</p>
<p><strong>cp /usr/local/mysql/lib/libmysqlclent*  /usr/lib(</strong><strong>真正解决办法</strong><strong>)</strong></p>
<p><strong>##运行 ldconfig，加载所有共享链接库</strong></p>
<p><strong>cp -a ftp  /var/www/html/pureftp</strong></p>
<p><strong>make &amp;&amp; make install</strong></p>
<p><strong>cp configuration-file/pure-config.pl  /usr/local/pureftpd/sbin/</strong></p>
<p><strong>chmod +x  /usr/local/pureftpd/sbin/pure-config.pl</strong></p>
<p><strong>cp configuration-file/pure-ftpd.conf  /etc</strong></p>
<p><strong>make /ftproot</strong></p>
<p><strong>生成</strong><strong>pure-Ftp</strong><strong>服务管理脚本</strong><strong> </strong></p>
<p><strong>编辑</strong><strong>contrib</strong><strong>子目录里面的</strong><strong>redhat.int</strong><strong>文件</strong><strong> </strong></p>
<p><strong>fullpath=/usr/local/sbin/$prog</strong></p>
<p><strong>改为</strong><strong> </strong></p>
<p><strong>fullpath=/usr/local/pureftpd/sbin/$prog</strong></p>
<p><strong>pureftpwho=/usr/local/sbin/pure-ftpwho</strong></p>
<p><strong>改为</strong><strong> </strong></p>
<p><strong>pureftpwho=/usr/local/pureftpd/sbin/pure-ftpwho</strong></p>
<p><strong>cp contrib/redhat.init  /etc/init.d/pure-ftpd</strong></p>
<p><strong>chmod +x /etc/init.d/pure-ftpd</strong></p>
<p><strong>chkconfig &#8211;add pure-ftpd</strong></p>
<p><strong>安装</strong><strong>user mamager for pure-ftpd</strong><strong>进行</strong><strong>Web</strong><strong>管理</strong><strong>pure-ftp</strong></p>
<p><strong>tar -xzvf ftp_v2.1.tar.gz</strong></p>
<p><strong>cp -a ftp  /var/www/html/pureftp</strong></p>
<p><strong>在浏览器输入。</strong><strong>IP/pureftp/install.php</strong></p>
<p><strong> </strong></p>
<p><strong>一步一步的创建！！</strong><strong> </strong></p>
<p><strong>Touch /etc/pureftp-mysql.conf</strong></p>
<p><strong>把下面复制到那个文件</strong><strong> </strong></p>
<pre>############################################################################</pre>
<pre>#                                                                           #</pre>
<pre># PureFTPd MySQL configuration file.                                        #</pre>
<pre># Generated by the installation wizard for the 'User manager for PureFTPd' #</pre>
<pre># See http://machiel.generaal.net for more info                             #</pre>
<pre># or read the README.MySQL for explanations of the syntax.                  #</pre>
<pre>#                                                                           #</pre>
<pre>############################################################################</pre>
<pre># Optional : MySQL server name or IP. Don't define this for unix sockets.</pre>
<pre>MYSQLServer      127.0.0.1</pre>
<pre># Optional : MySQL port. Don't define this if a local unix socket is used.</pre>
<pre># MYSQLPort        3306</pre>
<pre># Optional : define the location of mysql.sock if the server runs on this host.</pre>
<pre>MYSQLSocket      /tmp/mysql.sock</pre>
<pre># Mandatory : user to bind the server as.</pre>
<pre>MYSQLUser       ftp</pre>
<pre># Mandatory : user password. You must have a password.</pre>
<pre>MYSQLPassword    tmppasswd</pre>
<pre># Mandatory : database to open.</pre>
<pre>MYSQLDatabase  ftpusers</pre>
<pre># Mandatory : how passwords are stored</pre>
<pre># Valid values are : "cleartext", "crypt", "md5" and "password"</pre>
<pre># ("password" = MySQL password() function)</pre>
<pre># You can also use "any" to try "crypt", "md5" *and* "password"</pre>
<pre>MYSQLCrypt       md5</pre>
<pre># In the following directives, parts of the strings are replaced at</pre>
<pre># run-time before performing queries :</pre>
<pre>#</pre>
<pre># \L is replaced by the login of the user trying to authenticate.</pre>
<pre># \I is replaced by the IP address the user connected to.</pre>
<pre># \P is replaced by the port number the user connected to.</pre>
<pre># \R is replaced by the IP address the user connected from.</pre>
<pre># \D is replaced by the remote IP address, as a long decimal number.</pre>
<pre>#</pre>
<pre># Very complex queries can be performed using these substitution strings,</pre>
<pre># especially for virtual hosting.</pre>
<pre># Query to execute in order to fetch the password</pre>
<pre>MYSQLGetPW       SELECT Password FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Query to execute in order to fetch the system user name or uid</pre>
<pre>MYSQLGetUID      SELECT Uid FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Optional : default UID - if set this overrides MYSQLGetUID</pre>
<pre>#MYSQLDefaultUID 1000</pre>
<pre># Query to execute in order to fetch the system user group or gid</pre>
<pre>MYSQLGetGID      SELECT Gid FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Optional : default GID - if set this overrides MYSQLGetGID</pre>
<pre>#MYSQLDefaultGID 1000</pre>
<pre># Query to execute in order to fetch the home directory</pre>
<pre>MYSQLGetDir      SELECT Dir FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Optional : query to get the maximal number of files</pre>
<pre># Pure-FTPd must have been compiled with virtual quotas support.</pre>
<pre>MySQLGetQTAFS  SELECT QuotaFiles FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Optional : query to get the maximal disk usage (virtual quotas)</pre>
<pre># The number should be in Megabytes.</pre>
<pre># Pure-FTPd must have been compiled with virtual quotas support.</pre>
<pre>MySQLGetQTASZ  SELECT QuotaSize FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Optional : ratios. The server has to be compiled with ratio support.</pre>
<pre>MySQLGetRatioUL SELECT ULRatio FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre>MySQLGetRatioDL SELECT DLRatio FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Optional : bandwidth throttling.</pre>
<pre># The server has to be compiled with throttling support.</pre>
<pre># Values are in KB/s .</pre>
<pre>MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre>MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")</pre>
<pre># Enable ~ expansion. NEVER ENABLE THIS BLINDLY UNLESS :</pre>
<pre># 1) You know what you are doing.</pre>
<pre># 2) Real and virtual users match.</pre>
<pre># MySQLForceTildeExpansion 1</pre>
<pre># If you upgraded your tables to transactionnal tables (Gemini,</pre>
<pre># BerkeleyDB, Innobase...), you can enable SQL transactions to</pre>
<pre># avoid races. Leave this commented if you are using the</pre>
<pre># traditionnal MyIsam databases or old (&lt; 3.23.x) MySQL versions.</pre>
<pre># MySQLTransactions On</pre>
<p><strong>在</strong><strong>/etc/pure-ftp.conf</strong></p>
<p><strong>加一句</strong><strong> </strong></p>
<p><strong>MySQLConfigFile      /etc/pureftpd-mysql.conf</strong></p>
<p><strong></strong></p>
<p><strong>Service pure-ftpd start</strong></p>
<p></strong></p>
<p><strong></strong><strong></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/382/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CentOS x64 里php 源码编译出错参见情况及解决办法</title>
		<link>http://www.sphinxsearch.org/archives/378</link>
		<comments>http://www.sphinxsearch.org/archives/378#comments</comments>
		<pubDate>Fri, 02 Mar 2012 14:32:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[lamp]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=378</guid>
		<description><![CDATA[configure: error: xml2-config not found. Please check your libxml2 installation. yum install libxml2-devel.x86_64 configure: error: Cannot find OpenSSL’s yum install openssl-devel.x86_64 configure: error: Could not find pcre.h in /usr/local yum install pcre-devel.x86_64 configure: error: Could not find pcre.h in /usr/local "--with-pcre-regex=/usr/include" \ configure: error: Could not find libpcre.(a&#124;so) in /usr/include "--with-pcre-regex=/usr" \ configure: error: Please [...]]]></description>
			<content:encoded><![CDATA[<div id="post-280">
<p>configure: error: xml2-config not found. Please check your libxml2 installation.</p>
<div>
<pre>yum install libxml2-devel.x86_64</pre>
<p>configure: error: Cannot find OpenSSL’s</p>
<pre>yum install openssl-devel.x86_64</pre>
<p>configure: error: Could not find pcre.h in /usr/local</p>
<pre>yum install pcre-devel.x86_64</pre>
<p>configure: error: Could not find pcre.h in /usr/local</p>
<pre>"--with-pcre-regex=/usr/include" \</pre>
<p>configure: error: Could not find libpcre.(a|so) in /usr/include</p>
<pre>"--with-pcre-regex=/usr" \</pre>
<p>configure: error: Please reinstall the libcurl distribution -<br />
easy.h should be in /include/curl/</p>
<pre>yum install curl-devel.x86_64</pre>
<p>configure: error: libjpeg.(a|so) not found.</p>
<pre>yum install libjpeg-devel.x86_64</pre>
<p>configure: error: libpng.(a|so) not found.</p>
<pre>yum install libpng-devel.x86_64</pre>
<p>configure: error: freetype.h not found.</p>
<pre>yum install freetype-devel.x86_64</pre>
<p>configure: error: Please reinstall the iconv library.</p>
<pre>"--with-iconv" \</pre>
<p>configure: error: mcrypt.h not found. Please reinstall libmcrypt.</p>
<pre>yum install libmcrypt.x86_64 libmcrypt-devel.x86_64</pre>
<p>configure: error: Please reinstall libmhash – I cannot find mhash.h</p>
<pre>yum install mhash.x86_64 mhash-devel.x86_64</pre>
<p>Note that the MySQL client library is not bundled anymore!</p>
<pre>yum install php-mysql.x86_64 mysql-devel.x86_64</pre>
<p>configure: error: Please reinstall the BZip2 distribution</p>
<pre>yum install bzip2-devel.x86_64</pre>
<p>configure: error: utf8_mime2text() has new signature, but U8T_CANONICAL is missing. This should not happen. Check config.log for additional information.<br />
DISABLE IMAP<br />
configure: error: Cannot find pspell</p>
<pre>yum install aspell-devel.x86_64</pre>
<p>configure: error: Cannot find libtidy</p>
<pre>yum install libtidy.x86_64 libtidy-devel.x86_64</pre>
<p>error: xslt-config not found. Please reinstall the libxslt &gt;= 1.1.0 distribution</p>
<pre>yum install libxslt.x86_64 libxslt-devel.x86_64</pre>
<p>collect2: ld returned 1 exit status</p>
<pre>yum install glibc-utils.x86_64 libtool-ltdl-devel.x86_64</pre>
<h2>Step by step to guide PHP Compile</h2>
<p><strong>Step 1: </strong> Update &amp; Install Development Tools &amp; Libraries</p>
<pre>yum update
yum group install "Development Tools"
yum group install "Development Libraries"</pre>
<p><strong>Step 2:</strong> Run the bellow bash script</p>
<pre>#!/bin/sh
"./configure" \
"--prefix=/usr/local/php5" \
"--enable-force-cgi-redirect" \
"--enable-fastcgi" \
"--with-bz2" \
"--with-config-file-path=/usr/local/etc" \
"--with-config-file-scan-dir=/usr/local/etc/php.d" \
"--with-curl=/usr/local/lib" \
"--with-gd" \
"--with-gettext" \
"--with-jpeg-dir=/usr/local/lib" \
"--with-freetype-dir=/usr/local/lib" \
"--with-kerberos" \
"--with-mcrypt" \
"--with-mhash" \
"--with-mime-magic" \
"--with-mysql" \
"--with-mysqli" \
"--with-pcre-regex=/usr" \
"--with-pdo-mysql=shared" \
"--with-pdo-sqlite=shared" \
"--with-pear=/usr/local/lib/php" \
"--with-png-dir=/usr/local/lib" \
"--with-pspell" \
"--with-sqlite=shared" \
"--with-tidy" \
"--with-ttf" \
"--with-xmlrpc" \
"--with-xsl" \
"--with-zlib" \
"--with-zlib-dir=/usr/local/lib" \
"--with-openssl" \
"--with-iconv" \
"--with-libdir=lib64" \
"--enable-bcmath" \
"--enable-calendar" \
"--enable-exif" \
"--enable-ftp" \
"--enable-gd-native-ttf" \
"--enable-libxml" \
"--enable-magic-quotes" \
"--enable-soap" \
"--enable-sockets" \
"--enable-mbstring" \
"--enable-zip" \
"--enable-wddx"</pre>
<pre>from http://www.lifelinux.com/error-compiling-php-on-centos-x64/</pre>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/378/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于数据挖掘推荐系统实现</title>
		<link>http://www.sphinxsearch.org/archives/374</link>
		<comments>http://www.sphinxsearch.org/archives/374#comments</comments>
		<pubDate>Thu, 16 Feb 2012 13:39:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[数据挖掘]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=374</guid>
		<description><![CDATA[作者：张荣华 先说一说问题，不知道大家有没有这样的经验，反正我是经常碰到。 举例1，某些网站每隔几天就发邮件给我，每次发的邮件内容都是一些我根本不感兴趣的东西，我不甚其扰，对其深恶痛绝。 举例2，添加具有某功能的一个msn机器人，每天都有几次突然蹦出一个窗口，推荐一堆我根本不想知道的内容，烦不烦啊， 我只好将你阻止掉。 每一个观众只想看他感兴趣的东西，而不是一下与之无关的事物，那么如何才能知道观众的兴趣所在呢，还是数据挖掘，经过一番思考，终于有点思路，即根据用户以往的浏览历史来预测用户将来的行为，也就是基于内容的推荐。 基于内容的推荐（Content-based Recommendation）是信息过滤技术的延续与发展，它是建立在项目的内容信息上作出推荐的，而不需要依据用户对项目的评价意见，更多地需要用机器学习的方法从关于内容的特征描述的事例中得到用户的兴趣资料。在基于内容的推荐系统中，项目或对象是通过相关的特征的属性来定义，系统基于用户评价对象的特征，学习用户的兴趣，考察用户资料与待预测项目的相匹配程度。用户的资料模型取决于所用学习方法，常用的有决策树、神经网络和基于向量的表示方法等。基于内容的用户资料是需要有用户的历史数据，用户资料模型可能随着用户的偏好改变而发生变化。 基于内容推荐方法的优点是： 1）不需要其它用户的数据，没有冷开始问题和稀疏问题。 2）能为具有特殊兴趣爱好的用户进行推荐。 3）能推荐新的或不是很流行的项目，没有新项目问题。 4）通过列出推荐项目的内容特征，可以解释为什么推荐那些项目。 5）已有比较好的技术，如关于分类学习方面的技术已相当成熟。 缺点是要求内容能容易抽取成有意义的特征，要求特征内容有良好的结构性，并且用户的口味必须能够用内容特征形式来表达，不能显式地得到其它用户的判断情况。 要实现内容推荐系统总体来说要经过4个大的步骤： 1 搜集数据，即搜集用户的行为资料，其中也包括很多方法，根据我找到的资料与以往的经验来看，web日志可以作为我们的切入点，即我们的数据来源。 2 过滤数据，web日志中有很多无用的信息，我们要把这些无用的信息排除掉，而且要区分出用户和日志数据之间的联系。 3 分析数据，利用分类聚类技术分析出这些日志数据之间的关联性，以及这些日志数据和用户之间的关联性，这也是最重要的一步。 4 输出结果。 有了这个思路之后，我们可以着手做第一步，即日志数据的收集 我们知道，大多数的web服务器都是有自己的日志记录的，比如说apache安装之后有一个logs目录，其中就有它的日志文件，一般说来它有自己的一个格式，比如说： 1浏览器所在主机的 IP 地址(ip)； 2访问日期和时间(date-time)；3客户机与服务器通信所用的方法(methed，get or post)； 4客户机请求访问页面的 URL； 5服务器返回的状态(status)； 6客户端浏览器的类型； 但是这个日志文件有一些不能克服的问题，或者我不知道如何克服，那么我先说说我的疑问，首先，这个日志文件中记录的是ip地址，据了解，网络中有很多计算机的ip地址是相同的，因为他们在一个统一的路由后面，这个比例可能达到25%。那么我们就无法根据ip地址来唯一确定一个用户。其次，一般的web服务器中都会用多个应用，那么其他应用的访问信息对我们来说有可能是多余的。再者，web服务器的日志形式比较单一，灵活性不大，可定制的余地很小，在日志数据中有效数据所占的比例较小。还有，一些静态文件的请求也会被web服务器记录下来，比如说js文件，css文件，还有图片文件，等等这些东西对内容推荐来说都是无用的资源。 基于上面3点原因，我认为可以自定义日志数据。为了解决用户唯一性，我们让应用为每一个浏览器生成一个clientId保存在对应的浏览器上，这样该浏览器只要访问网站，我们就可以确定这个浏览器的唯一性，当然我们仍然不能确定浏览器使用者的唯一性，但是我们可以更进一步，如果浏览器的使用者登陆网站的话，我们就可以使用用户id来确定用户的唯一性，不过大多数网站用户可能在使用网站的时候并不会登陆，我也是这样，没有关系，即使使用clientId问题也不会太大，随着社会的发展，计算机的拥有量逐渐增加，一般来说一个人只会使用一台固定的电脑，在公司里尤其是这样。所以我认为clientId的方案是可行的，也许有人要问，别人的浏览器禁止了cookie怎么办，那么我只能说没有办法，不过还好事实是绝大多数人都没有这样做。 接下来我们可以定义一下我们所需要的日志数据的格式，比如这样， ip，clientId，userId，url，datetime，get or post等等。 这样数据有效性会大大提高。 在得到较为有效的数据之后，我们还需要对这些数据进行再次过滤： 1 去掉一些非内容的url，这些数据也是无效数据，这些非内容的url需要我们自己手工的统计出来，然后和日志数据中的数据进行比对，将这些非内容数据从日志数据中清除出去。 2 同时我们也需要把post请求从日志数据中清除出去，或者我们在记录日志的时候根本不应该把post请求记录下来。 经过以上步骤之后我们就可以开始第3个阶段了，统计每个用户的访问的url，对这些url进行访问，得到对应的html中所包含的数据，这些数据都是文本，将有用的文本提取出来，然后对这些有用的文本进行聚类。这样就可以得到每个用户喜欢的几个类别。 聚类完成之后我们就可以开始分类了，即把最新的文章或者内容和对应的类别进行匹配，匹配成功之后，我们可以认为这个新文章或者内容可以推荐给对应的用户。 问题：以上的流程只适用于没有使用缓存的系统，但是一般大型的网站都会使用varnish，squid等等，使用它们之后我们就无法得到用户访问的日志数据了，所以如果使用了varnish或者squid，我们不得不再次面对web服务器的日志数据。 在不考虑varnish或者squid的情况下，使用lucene+jamon+htmlparse基本就可以实现以上推荐系统。]]></description>
			<content:encoded><![CDATA[<p>作者：张荣华</p>
<p>先说一说问题，不知道大家有没有这样的经验，反正我是经常碰到。</p>
<p>举例1，某些网站每隔几天就发邮件给我，每次发的邮件内容都是一些我根本不感兴趣的东西，我不甚其扰，对其深恶痛绝。<br />
举例2，添加具有某功能的一个msn机器人，每天都有几次突然蹦出一个窗口，推荐一堆我根本不想知道的内容，烦不烦啊， 我只好将你阻止掉。</p>
<p>每一个观众只想看他感兴趣的东西，而不是一下与之无关的事物，那么如何才能知道观众的兴趣所在呢，还是数据挖掘，经过一番思考，终于有点思路，即根据用户以往的浏览历史来预测用户将来的行为，也就是基于内容的推荐。<br />
基于内容的推荐（Content-based Recommendation）是信息过滤技术的延续与发展，它是建立在项目的内容信息上作出推荐的，而不需要依据用户对项目的评价意见，更多地需要用机器学习的方法从关于内容的特征描述的事例中得到用户的兴趣资料。在基于内容的推荐系统中，项目或对象是通过相关的特征的属性来定义，系统基于用户评价对象的特征，学习用户的兴趣，考察用户资料与待预测项目的相匹配程度。用户的资料模型取决于所用学习方法，常用的有决策树、神经网络和基于向量的表示方法等。基于内容的用户资料是需要有用户的历史数据，用户资料模型可能随着用户的偏好改变而发生变化。</p>
<p>基于内容推荐方法的优点是：<br />
1）不需要其它用户的数据，没有冷开始问题和稀疏问题。<br />
2）能为具有特殊兴趣爱好的用户进行推荐。<br />
3）能推荐新的或不是很流行的项目，没有新项目问题。<br />
4）通过列出推荐项目的内容特征，可以解释为什么推荐那些项目。<br />
5）已有比较好的技术，如关于分类学习方面的技术已相当成熟。</p>
<p>缺点是要求内容能容易抽取成有意义的特征，要求特征内容有良好的结构性，并且用户的口味必须能够用内容特征形式来表达，不能显式地得到其它用户的判断情况。</p>
<p>要实现内容推荐系统总体来说要经过4个大的步骤：<br />
1 搜集数据，即搜集用户的行为资料，其中也包括很多方法，根据我找到的资料与以往的经验来看，web日志可以作为我们的切入点，即我们的数据来源。</p>
<p>2 过滤数据，web日志中有很多无用的信息，我们要把这些无用的信息排除掉，而且要区分出用户和日志数据之间的联系。</p>
<p>3 分析数据，利用分类聚类技术分析出这些日志数据之间的关联性，以及这些日志数据和用户之间的关联性，这也是最重要的一步。</p>
<p>4 输出结果。</p>
<p>有了这个思路之后，我们可以着手做第一步，即日志数据的收集<br />
我们知道，大多数的web服务器都是有自己的日志记录的，比如说apache安装之后有一个logs目录，其中就有它的日志文件，一般说来它有自己的一个格式，比如说：<br />
1浏览器所在主机的 IP 地址(ip)； 2访问日期和时间(date-time)；3客户机与服务器通信所用的方法(methed，get or post)； 4客户机请求访问页面的 URL； 5服务器返回的状态(status)； 6客户端浏览器的类型；</p>
<p>但是这个日志文件有一些不能克服的问题，或者我不知道如何克服，那么我先说说我的疑问，首先，这个日志文件中记录的是ip地址，据了解，网络中有很多计算机的ip地址是相同的，因为他们在一个统一的路由后面，这个比例可能达到25%。那么我们就无法根据ip地址来唯一确定一个用户。其次，一般的web服务器中都会用多个应用，那么其他应用的访问信息对我们来说有可能是多余的。再者，web服务器的日志形式比较单一，灵活性不大，可定制的余地很小，在日志数据中有效数据所占的比例较小。还有，一些静态文件的请求也会被web服务器记录下来，比如说js文件，css文件，还有图片文件，等等这些东西对内容推荐来说都是无用的资源。</p>
<p>基于上面3点原因，我认为可以自定义日志数据。为了解决用户唯一性，我们让应用为每一个浏览器生成一个clientId保存在对应的浏览器上，这样该浏览器只要访问网站，我们就可以确定这个浏览器的唯一性，当然我们仍然不能确定浏览器使用者的唯一性，但是我们可以更进一步，如果浏览器的使用者登陆网站的话，我们就可以使用用户id来确定用户的唯一性，不过大多数网站用户可能在使用网站的时候并不会登陆，我也是这样，没有关系，即使使用clientId问题也不会太大，随着社会的发展，计算机的拥有量逐渐增加，一般来说一个人只会使用一台固定的电脑，在公司里尤其是这样。所以我认为clientId的方案是可行的，也许有人要问，别人的浏览器禁止了cookie怎么办，那么我只能说没有办法，不过还好事实是绝大多数人都没有这样做。</p>
<p>接下来我们可以定义一下我们所需要的日志数据的格式，比如这样，<br />
ip，clientId，userId，url，datetime，get or post等等。<br />
这样数据有效性会大大提高。</p>
<p>在得到较为有效的数据之后，我们还需要对这些数据进行再次过滤：<br />
1 去掉一些非内容的url，这些数据也是无效数据，这些非内容的url需要我们自己手工的统计出来，然后和日志数据中的数据进行比对，将这些非内容数据从日志数据中清除出去。<br />
2 同时我们也需要把post请求从日志数据中清除出去，或者我们在记录日志的时候根本不应该把post请求记录下来。</p>
<p>经过以上步骤之后我们就可以开始第3个阶段了，统计每个用户的访问的url，对这些url进行访问，得到对应的html中所包含的数据，这些数据都是文本，将有用的文本提取出来，然后对这些有用的文本进行聚类。这样就可以得到每个用户喜欢的几个类别。</p>
<p>聚类完成之后我们就可以开始分类了，即把最新的文章或者内容和对应的类别进行匹配，匹配成功之后，我们可以认为这个新文章或者内容可以推荐给对应的用户。</p>
<p>问题：以上的流程只适用于没有使用缓存的系统，但是一般大型的网站都会使用varnish，squid等等，使用它们之后我们就无法得到用户访问的日志数据了，所以如果使用了varnish或者squid，我们不得不再次面对web服务器的日志数据。</p>
<p>在不考虑varnish或者squid的情况下，使用lucene+jamon+htmlparse基本就可以实现以上推荐系统。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/374/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL联表查询及联表删除的方法</title>
		<link>http://www.sphinxsearch.org/archives/370</link>
		<comments>http://www.sphinxsearch.org/archives/370#comments</comments>
		<pubDate>Tue, 27 Dec 2011 16:34:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=370</guid>
		<description><![CDATA[MySQL联表查询及联表删除都是经常需要用到的操作，下面对MySQL联表查询和联表删除都作了详细的介绍分析，希望对您有所帮助。 MySQL联表查询： reference mysql manul: 3.2.7. SELECT语法13.2.7.1. JOIN语法 13.2.7.2. UNION语法 eg1:·mysql&#62; SELECT t1.name, t2.salary FROM employee AS t1, info AS t2·-&#62;    WHERE t1.name = t2.name;eg2:·mysql&#62; SELECT table1.* FROM table1·-&#62;        LEFT JOIN table2 ON table1.id=table2.id·-&#62;        WHERE table2.id IS NULL; 联表删除： 1、从数据表t1 中把那些id值在数据表t2 里有匹配的记录全删除掉 DELETE t1 FROM t1,t2 WHERE t1.id=t2.id    或DELETE  FROM t1 USING t1,t2 WHERE t1.id=t2.id [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL联表查询及联表删除都是经常需要用到的操作，下面对<a href="http://database.51cto.com/art/201010/229528.htm">MySQL</a>联表查询和联表删除都作了详细的介绍分析，希望对您有所帮助。</p>
<p>MySQL联表查询：</p>
<p>reference mysql manul:<br />
3.2.7. SELECT语法13.2.7.1. JOIN语法<br />
13.2.7.2.  UNION语法<br />
eg1:·mysql&gt; SELECT t1.name, t2.salary FROM employee AS t1, info AS  t2·-&gt;    WHERE t1.name = t2.name;eg2:·mysql&gt; SELECT table1.* FROM  table1·-&gt;        LEFT JOIN table2 ON table1.id=table2.id·-&gt;        WHERE  table2.id IS NULL;</p>
<p>联表删除：</p>
<p>1、从数据表t1 中把那些id值在数据表t2 里有匹配的记录全删除掉</p>
<p>DELETE t1 FROM t1,t2 WHERE t1.id=t2.id    或DELETE  FROM t1 USING t1,t2 WHERE  t1.id=t2.id</p>
<p>2、从数据表t1里在数据表t2里没有匹配的记录查找出来并删除掉</p>
<p>DELETE t1 FROM t1 LEFT JOIN T2 ON t1.id=t2.id WHERE t2.id IS NULL 或</p>
<p>DELETE  FROM t1,USING t1 LEFT JOIN T2 ON t1.id=t2.id WHERE t2.id IS NULL</p>
<p>3、从两个表中找出相同记录的数据并把两个表中的数据都删除掉</p>
<p>DELETE t1,t2 from t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t1.id=25</p>
<p>注意此处的delete t1,t2 from 中的t1,t2不能是别名</p>
<p>如：delete t1,t2 from table_name as t1 left join table2_name as t2 on  t1.id=t2.id where table_name.id=25 在数据里面执行是错误的（MYSQL 版本不小于5.0在5.0中是可以的）</p>
<p>上述语句改写成</p>
<p>delete table_name,table2_name from table_name as t1 left join table2_name as  t2 on t1.id=t2.id where table_name.id=25 在数据里面执行是错误的（MYSQL 版本小于5.0在5.0中是可以的）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/370/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>十大数据挖掘算法及各自优势</title>
		<link>http://www.sphinxsearch.org/archives/367</link>
		<comments>http://www.sphinxsearch.org/archives/367#comments</comments>
		<pubDate>Thu, 22 Sep 2011 04:26:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[数据挖掘]]></category>

		<guid isPermaLink="false">http://www.sphinxsearch.org/?p=367</guid>
		<description><![CDATA[收藏一篇不错的 数据挖掘算法介绍的文章]]></description>
			<content:encoded><![CDATA[<p>国际权威的学术组织the IEEE International Conference on Data Mining (ICDM) 2006年12月评选出了数据挖掘领域的十大经典算法：C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, kNN, Naive Bayes, and CART.</p>
<p>不仅仅是选中的十大算法，其实参加评选的18种算法，实际上随便拿出一种来都可以称得上是经典算法，它们在数据挖掘领域都产生了极为深远的影响。</p>
<p>1. C4.5</p>
<p>C4.5算法是机器学习算法中的一种分类决策树算法,其核心算法是ID3算法. C4.5算法继承了ID3算法的优点，并在以下几方面对ID3算法进行了改进：</p>
<p>1) 用信息增益率来选择属性，克服了用信息增益选择属性时偏向选择取值多的属性的不足；</p>
<p>2) 在树构造过程中进行剪枝；</p>
<p>3) 能够完成对连续属性的离散化处理；</p>
<p>4) 能够对不完整数据进行处理。</p>
<p>C4.5算法有如下优点：产生的分类规则易于理解，准确率较高。其缺点是：在构造树的过程中，需要对数据集进行多次的顺序扫描和排序，因而导致算法的低效。</p>
<p>2. The k-means algorithm 即K-Means算法</p>
<p>k-means algorithm算法是一个聚类算法，把n的对象根据他们的属性分为k个分割，k &lt; n。它与处理混合正态分布的最大期望算法很相似，因为他们都试图找到数据中自然聚类的中心。它假设对象属性来自于空间向量，并且目标是使各个群组内部的均方误差总和最小。</p>
<p>3. Support vector machines</p>
<p>支持向量机，英文为Support Vector Machine，简称SV机（论文中一般简称SVM）。它是一种監督式學習的方法，它广泛的应用于统计分类以及回归分析中。支持向量机将向量映射到一个更高维的空间里，在这个空间里建立有一个最大间隔超平面。在分开数据的超平面的两边建有两个互相平行的超平面。分隔超平面使两个平行超平面的距离最大化。假定平行超平面间的距离或差距越大，分类器的总误差越小。一个极好的指南是C.J.C Burges的《模式识别支持向量机指南》。van der Walt 和 Barnard 将支持向量机和其他分类器进行了比较。</p>
<p>4. The Apriori algorithm</p>
<p>Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。其核心是基于两阶段频集思想的递推算法。该关联规则在分类上属于单维、单层、布尔关联规则。在这里，所有支持度大于最小支持度的项集称为频繁项集，简称频集。</p>
<p>5. 最大期望(EM)算法</p>
<p>在统计计算中，最大期望（EM，Expectation–Maximization）算法是在概率（probabilistic）模型中寻找参数最大似然估计的算法，其中概率模型依赖于无法观测的隐藏变量（Latent Variabl）。最大期望经常用在机器学习和计算机视觉的数据集聚（Data Clustering）领域。</p>
<p>6. PageRank</p>
<p>PageRank是Google算法的重要内容。2001年9月被授予美国专利，专利人是Google创始人之一拉里·佩奇（Larry Page）。因此，PageRank里的page不是指网页，而是指佩奇，即这个等级方法是以佩奇来命名的。</p>
<p>PageRank根据网站的外部链接和内部链接的数量和质量俩衡量网站的价值。PageRank背后的概念是，每个到页面的链接都是对该页面的一次投票，被链接的越多，就意味着被其他网站投票越多。这个就是所谓的“链接流行度”——衡量多少人愿意将他们的网站和你的网站挂钩。PageRank这个概念引自学术中一篇论文的被引述的频度——即被别人引述的次数越多，一般判断这篇论文的权威性就越高。</p>
<p>7. AdaBoost</p>
<p>Adaboost是一种迭代算法，其核心思想是针对同一个训练集训练不同的分类器(弱分类器)，然后把这些弱分类器集合起来，构成一个更强的最终分类器 (强分类器)。其算法本身是通过改变数据分布来实现的，它根据每次训练集之中每个样本的分类是否正确，以及上次的总体分类的准确率，来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练，最后将每次训练得到的分类器最后融合起来，作为最后的决策分类器。</p>
<p>8. kNN: k-nearest neighbor classification</p>
<p>K最近邻(k-Nearest Neighbor，KNN)分类算法，是一个理论上比较成熟的方法，也是最简单的机器学习算法之一。该方法的思路是：如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别，则该样本也属于这个类别。</p>
<p>9. Naive Bayes</p>
<p>在众多的分类模型中，应用最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型（Naive Bayesian Model，NBC）。 朴素贝叶斯模型发源于古典数学理论，有着坚实的数学基础，以及稳定的分类效率。同时，NBC模型所需估计的参数很少，对缺失数据不太敏感，算法也比较简单。理论上，NBC模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此，这是因为NBC模型假设属性之间相互独立，这个假设在实际应用中往往是不成立的，这给NBC模型的正确分类带来了一定影响。在属性个数比较多或者属性之间相关性较大时，NBC模型的分类效率比不上决策树模型。而在属性相关性较小时，NBC模型的性能最为良好。</p>
<p>10. CART: 分类与回归树</p>
<p>CART, Classification and Regression Trees。 在分类树下面有两个关键的思想。第一个是关于递归地划分自变量空间的想法；第二个想法是用验证数据进行剪枝。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sphinxsearch.org/archives/367/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

