<?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>风叶</title>
	<atom:link href="http://blog.myhnet.cn/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.myhnet.cn</link>
	<description>秋湍泻石髓 风叶聚云根</description>
	<lastBuildDate>Fri, 20 Aug 2010 15:05:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Awk学习笔记[转]</title>
		<link>http://blog.myhnet.cn/2010/08/20/how-to-use-awk/</link>
		<comments>http://blog.myhnet.cn/2010/08/20/how-to-use-awk/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 10:59:06 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[脚本]]></category>
		<category><![CDATA[脚本编程]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[字符处理]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1057</guid>
		<description><![CDATA[整理：Jims of 肥肥世家 注：此文中所有链接如无特别说明均已失效，本文尽为保护作者利益而保留。请谨慎点击 &#60;jims.yang@gmail.com&#62; Copyright © 2004 本文遵从GPL协议，欢迎转载、修改、散布。 第一次发布时间:2004年8月6日 Table of Contents 1. awk简介 2. awk命令格式和选项 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;2.1. awk的语法有两种形式 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;2.2. 命令选项 3. 模式和操作 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;3.1. 模式 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;3.2. 操作 4. awk的环境变量 5. awk运算符 6. 记录和域 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;6.1. 记录 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;6.2. 域 &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;6.3. 域分隔符 7. gawk专用正则表达式元字符 8. POSIX字符集 9. 匹配操作符(~) 10. 比较表达式 11. 范围模板 12. 一个验证passwd文件有效性的例子 13. 几个实例 14. awk编程 [...]]]></description>
			<content:encoded><![CDATA[<p>整理：Jims of  <a href="http://www.ringkee.com/" target="_top">肥肥世家</a><br />
<small><font color=red>注：此文中所有链接如无特别说明均已失效，本文尽为保护作者利益而保留。请谨慎点击</font></small></p>
<p>&lt;<a href="mailto:jims.yang@gmail.com">jims.yang@gmail.com</a>&gt;</p>
<p>Copyright © 2004 本文遵从GPL协议，欢迎转载、修改、散布。</p>
<p>第一次发布时间:2004年8月6日</p>
<p>Table of Contents</p>
<p><a href="#awk01">1. awk简介</a><br />
<a href="#awk02">2. awk命令格式和选项</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0201">2.1. awk的语法有两种形式</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0202">2.2. 命令选项</a><br />
<a href="#awk03">3. 模式和操作</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0301">3.1. 模式</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0302">3.2. 操作</a><br />
<a href="#awk04">4. awk的环境变量</a><br />
<a href="#awk05">5. awk运算符</a><br />
<a href="#awk06">6. 记录和域</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0601">6.1. 记录</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0602">6.2. 域</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk0603">6.3. 域分隔符</a><br />
<a href="#awk07">7. gawk专用正则表达式元字符</a><br />
<a href="#awk08">8. POSIX字符集</a><br />
<a href="#awk09">9. 匹配操作符(~)</a><br />
<a href="#awk10">10. 比较表达式</a><br />
<a href="#awk11">11. 范围模板</a><br />
<a href="#awk12">12. 一个验证passwd文件有效性的例子</a><br />
<a href="#awk13">13. 几个实例</a><br />
<a href="#awk14">14. awk编程</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1401">14.1. 变量</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1402">14.2. BEGIN模块</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1403">14.3. END模块</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1404">14.4. 重定向和管道</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1405">14.5. 条件语句</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1406">14.6. 循环</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1407">14.7. 数组</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#awk1408">14.8. awk的内建函数</a><br />
<a href="#awk15">15. How-to</a><br />
<span id="more-1057"></span><br />
<a name="awk01"></a><br />
<h2>1. awk简介</h2>
<p>awk 是一种编程语言，用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件，或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能，是linux/unix下的一个强大编程工具。它在命令行中使用，但更多是作为脚本来使用。awk的处理文本和数据的方式是这样的，它逐行扫描文件，从第一行到最后一行，寻找匹配的特定模式的行，并在这些行上进行你想要的操作。如果没有指定处理动作，则把匹配的行显示到标准输出 (屏幕)，如果没有指定模式，则所有被操作所指定的行都被处理。awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人，分别是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的GNU版本，它提供了Bell实验室和GNU的一些扩展。下面介绍的awk是以GUN的gawk为例的，在 linux系统中已把awk链接到gawk，所以下面全部以awk进行介绍。<br />
<a name="awk02"></a><br />
<h2>2. awk命令格式和选项</h2>
<p><a name="awk0201"></a><br />
<h3>2.1. awk的语法有两种形式</h3>
<ul>
<li>awk [options] &#8216;script&#8217; var=value file(s)</li>
<li>awk [options] -f scriptfile var=value file(s)</li>
</ul>
<p><a name="awk0202"></a><br />
<h3>2.2. 命令选项</h3>
<pre>-F fs or --field-separator fs
    指定输入文件折分隔符，fs是一个字符串或者是一个正则表达式，如-F:。

-v var=value or --asign var=value
    赋值一个用户定义变量。

-f scripfile or --file scriptfile
    从脚本文件中读取awk命令。

-mf nnn and -mr nnn
    对nnn值设置内在限制，-mf选项限制分配给nnn的最大块数目；-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能，在标准awk中不适用。

-W compact or --compat, -W traditional or --traditional
    在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样，所有的awk扩展都被忽略。

-W copyleft or --copyleft, -W copyright or --copyright
    打印简短的版权信息。

-W help or --help, -W usage or --usage
    打印全部awk选项和每个选项的简短说明。

-W lint or --lint
    打印不能向传统unix平台移植的结构的警告。

-W lint-old or --lint-old
    打印关于不能向传统unix平台移植的结构的警告。

-W posix
    打开兼容模式。但有以下限制，不识别：\x、函数关键字、func、换码序列以及当fs是一个空格时，将新行作为一个域分隔符；操作符**和**=不能代替^和^=；fflush无效。

-W re-interval or --re-inerval
    允许间隔正则表达式的使用，参考(grep中的Posix字符类)，如括号表达式[[:alpha:]]。

-W source program-text or --source program-text
    使用program-text作为源代码，可与-f命令混用。

-W version or --version
    打印bug报告信息的版本。</pre>
<p><a name="awk03"></a><br />
<h2>3. 模式和操作</h2>
<p>awk脚本是由模式和操作组成的：<br />
    pattern {action} 如$ awk &#8216;/root/&#8217; test，或$ awk &#8216;$3 < 100' test。</p>
<p>两者是可选的，如果没有模式，则action应用到全部记录，如果没有action，则输出匹配全部记录。默认情况下，每一个输入行都是一条记录，但用户可通过RS变量指定不同的分隔符进行分隔。</p>
<p><a name="awk0301"></a><br />
<h3>3.1. 模式</h3>
<p>模式可以是以下任意一个：
<ul>
<li>/正则表达式/：使用通配符的扩展集。</li>
<li>关系表达式：可以用下面运算符表中的关系运算符进行操作，可以是字符串或数字的比较，如$2>%1选择第二个字段比第一个字段长的行。</li>
<li>模式匹配表达式：用运算符~(匹配)和~!(不匹配)。</li>
<li>模式，模式：指定一个行的范围。该语法不能包括BEGIN和END模式。</li>
<li>BEGIN：让用户指定在第一条输入记录被处理之前所发生的动作，通常可在这里设置全局变量。</li>
<li>END：让用户在最后一条输入记录被读取之后发生的动作。</li>
</ul>
<p><a name="awk0302"></a><br />
<h3>3.2. 操作</h3>
<p>操作由一人或多个命令、函数、表达式组成，之间由换行符或分号隔开，并位于大括号内。主要有四部份：
<ul>
<li>变量或数组赋值</li>
<li>输出命令</li>
<li>内置函数</li>
<li>控制流命令</li>
</ul>
<p><a name="awk04"></a><br />
<h2>4. awk的环境变量</h2>
<p>Table 1. awk的环境变量<br />
<table border=1>
<tr>
<th>变量</th>
<th>描述</th>
</tr>
<tr>
<td>$n</td>
<td>当前记录的第n个字段，字段间由FS分隔。</td>
</tr>
<tr>
<td>$0</td>
<td>完整的输入记录。</td>
</tr>
<tr>
<td>ARGC</td>
<td>命令行参数的数目。</td>
</tr>
<tr>
<td>ARGIND</td>
<td>命令行中当前文件的位置(从0开始算)。</td>
</tr>
<tr>
<td>ARGV</td>
<td>包含命令行参数的数组。</td>
</tr>
<tr>
<td>CONVFMT</td>
<td>数字转换格式(默认值为%.6g)</td>
</tr>
<tr>
<td>ENVIRON</td>
<td>环境变量关联数组。</td>
</tr>
<tr>
<td>ERRNO</td>
<td>最后一个系统错误的描述。</td>
</tr>
<tr>
<td>FIELDWIDTHS</td>
<td>字段宽度列表(用空格键分隔)。</td>
</tr>
<tr>
<td>FILENAME</td>
<td>当前文件名。</td>
</tr>
<tr>
<td>FNR</td>
<td>同NR，但相对于当前文件。</td>
</tr>
<tr>
<td>FS</td>
<td>字段分隔符(默认是任何空格)。</td>
</tr>
<tr>
<td>IGNORECASE</td>
<td>如果为真，则进行忽略大小写的匹配。</td>
</tr>
<tr>
<td>NF</td>
<td>当前记录中的字段数。</td>
</tr>
<tr>
<td>NR</td>
<td>当前记录数。</td>
</tr>
<tr>
<td>OFMT</td>
<td>数字的输出格式(默认值是%.6g)。</td>
</tr>
<tr>
<td>OFS</td>
<td>输出字段分隔符(默认值是一个空格)。</td>
</tr>
<tr>
<td>ORS</td>
<td>输出记录分隔符(默认值是一个换行符)。</td>
</tr>
<tr>
<td>RLENGTH</td>
<td>由match函数所匹配的字符串的长度。</td>
</tr>
<tr>
<td>RS</td>
<td>记录分隔符(默认是一个换行符)。</td>
</tr>
<tr>
<td>RSTART</td>
<td>由match函数所匹配的字符串的第一个位置。</td>
</tr>
<tr>
<td>SUBSEP</td>
<td>数组下标分隔符(默认值是\034)。</td>
</tr>
</table>
<p><a name="awk05"></a><br />
<h2>5. awk运算符</h2>
<p>Table 2. 运算符<br />
<table border=1>
<tr>
<th>运算符</th>
<th>描述</th>
</tr>
<tr>
<td>= += -= *= /= %= ^= **=</td>
<td>赋值</td>
</tr>
<tr>
<td>?:</td>
<td>C条件表达式</td>
</tr>
<tr>
<td>||</td>
<td>逻辑或</td>
</tr>
<tr>
<td>&#038;&#038;</td>
<td>逻辑与</td>
</tr>
<tr>
<td>~ ~!</td>
<td>匹配正则表达式和不匹配正则表达式</td>
</tr>
<tr>
<td>< <= > >= != ==</td>
<td>关系运算符</td>
</tr>
<tr>
<td>空格</td>
<td>连接</td>
</tr>
<tr>
<td>+ -</td>
<td>加，减</td>
</tr>
<tr>
<td>* / &#038;</td>
<td>乘，除与求余</td>
</tr>
<tr>
<td>+ &#8211; !</td>
<td>一元加，减和逻辑非</td>
</tr>
<tr>
<td>^ ***</td>
<td>求幂</td>
</tr>
<tr>
<td>++ &#8211;</td>
<td>增加或减少，作为前缀或后缀</td>
</tr>
<tr>
<td>$</td>
<td>字段引用</td>
</tr>
<tr>
<td>in</td>
<td>数组成员</td>
</tr>
</table>
<p><a name="awk06"></a><br />
<h2>6. 记录和域</h2>
<p><a name="awk0601"></a><br />
<h3>6.1. 记录</h3>
<p>awk把每一个以换行符结束的行称为一个记录。<br />
记录分隔符：默认的输入和输出的分隔符都是回车，保存在内建变量ORS和RS中。<br />
$0变量：它指的是整条记录。如$ awk &#8216;{print $0}&#8217; test将输出test文件中的所有记录。<br />
变量NR：一个计数器，每处理完一条记录，NR的值就增加1。如$ awk &#8216;{print NR,$0}&#8217; test将输出test文件中所有记录，并在记录前显示记录号。</p>
<p><a name="awk0602"></a><br />
<h3>6.2. 域</h3>
<p>记录中每个单词称做“域”，默认情况下以空格或tab分隔。awk可跟踪域的个数，并在内建变量NF中保存该值。如$ awk &#8216;{print $1,$3}&#8217; test将打印test文件中第一和第三个以空格分开的列(域)。</p>
<p><a name="awk0603"></a><br />
<h3>6.3. 域分隔符</h3>
<p>内建变量FS保存输入域分隔符的值，默认是空格或tab。我们可以通过-F命令行选项修改FS的值。如$ awk -F: &#8216;{print $1,$5}&#8217; test将打印以冒号为分隔符的第一，第五列的内容。</p>
<p>可以同时使用多个域分隔符，这时应该把分隔符写成放到方括号中，如$awk -F&#8217;[:\t]&#8216; &#8216;{print $1,$3}&#8217; test，表示以空格、冒号和tab作为分隔符。</p>
<p>输出域的分隔符默认是一个空格，保存在OFS中。如$ awk -F: &#8216;{print $1,$5}&#8217; test，$1和$5间的逗号就是OFS的值。</p>
<p><a name="awk07"></a><br />
<h2>7. gawk专用正则表达式元字符</h2>
<p>一般通用的元字符集就不讲了，可参考我的<a href="http://www.ringkee.com/jims/technic_folder/sed.htm">Sed</a>和<a href="http://www.ringkee.com/jims/technic_floder/grep.htm">Grep</a>学习笔记。以下几个是gawk专用的，不适合unix版本的awk。</p>
<pre>
\Y
    匹配一个单词开头或者末尾的空字符串。

\B
    匹配单词内的空字符串。

\<
    匹配一个单词的开头的空字符串，锚定开始。

\>
    匹配一个单词的末尾的空字符串，锚定末尾。

\w
    匹配一个字母数字组成的单词。

\W
    匹配一个非字母数字组成的单词。

\‘
    匹配字符串开头的一个空字符串。

\'
    匹配字符串末尾的一个空字符串。</pre>
<p><a name="awk08"></a><br />
<h2>8. POSIX字符集</h2>
<p>可参考我的<a href="http://www.ringkee.com/jims/technic_folder/grep.htm">Grep学习笔记</a></p>
<p><a name="awk09"></a><br />
<h2>9. 匹配操作符(~)</h2>
<p>用来在记录或者域内匹配正则表达式。如$ awk &#8216;$1 ~/^root/&#8217; test将显示test文件第一列中以root开头的行。</p>
<p><a name="awk10"></a><br />
<h2>10. 比较表达式</h2>
<p>conditional expression1 ? expression2: expression3，例如：$ awk &#8216;{max = $1 > $3 ? $1: $3; print max}&#8217; test。如果第一个域大于第三个域，$1就赋值给max，否则$3就赋值给max。</p>
<p>$ awk &#8216;$1 + $2 < 100' test。如果第一和第二个域相加大于100，则打印这些行。</p>
<p>$ awk '$1 > 5 &#038;&#038; $2 < 10' test,如果第一个域大于5，并且第二个域小于10，则打印这些行。</p>
<p><a name="awk11"></a><br />
<h2>11. 范围模板</h2>
<p>范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现，则匹配到开头或末尾。如$ awk &#8216;/root/,/mysql/&#8217; test将显示root第一次出现到mysql第一次出现之间的所有行。</p>
<p><a name="awk12"></a><br />
<h2>12. 一个验证passwd文件有效性的例子</h2>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline">$ cat /etc/passwd | awk -F: '\</li>
<li>NF != 7{\</li>
<li>printf(&quot;line %d,does not have 7 fields:%s\n&quot;,NR,$0)}\</li>
<li>$1 !~ /[A-Za-z0-9]/{printf(&quot;line %d,non alpha and numeric user id:%d: %s\n,NR,$0)}\</li>
<li>$2 == &quot;*&quot; {printf(&quot;line %d, no password: %s\n&quot;,NR,$0)}'</li></ol></div>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline">cat把结果输出给awk，awk把域之间的分隔符设为冒号。</li>
<li>如果域的数量(NF)不等于7，就执行下面的程序。</li>
<li>printf打印字符串&quot;line ?? does not have 7 fields&quot;，并显示该条记录。</li>
<li>如果第一个域没有包含任何字母和数字，printf打印“no alpha and numeric user id&quot; ，并显示记录数和记录。</li>
<li>如果第二个域是一个星号，就打印字符串“no passwd”，紧跟着显示记录数和记录本身。</li></ol></div>
<p><a name="awk13"></a><br />
<h2>13. 几个实例</h2>
<ul>
<li>$ awk &#8216;/^(no|so)/&#8217; test&#8212;&#8211;打印所有以模式no或so开头的行。</li>
<li>$ awk &#8216;/^[ns]/{print $1}&#8217; test&#8212;&#8211;如果记录以n或s开头，就打印这个记录。</li>
<li>$ awk &#8216;$1 ~/[0-9][0-9]$/(print $1}&#8217; test&#8212;&#8211;如果第一个域以两个数字结束就打印这个记录。</li>
<li>$ awk &#8216;$1 == 100 || $2 < 50' test-----如果第一个或等于100或者第二个域小于50，则打印该行。</li>
<li>$ awk &#8216;$1 != 10&#8242; test&#8212;&#8211;如果第一个域不等于10就打印该行。</li>
<li>$ awk &#8216;/test/{print $1 + 10}&#8217; test&#8212;&#8211;如果记录包含正则表达式test，则第一个域加10并打印出来。</li>
<li>$ awk &#8216;{print ($1 > 5 ? &#8220;ok &#8220;$1: &#8220;error&#8221;$1)}&#8217; test&#8212;&#8211;如果第一个域大于5则打印问号后面的表达式值，否则打印冒号后面的表达式值。</li>
<li>$ awk &#8216;/^root/,/^mysql/&#8217; test&#8212;-打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录，则继续打印直到下一个以正则表达式mysql开头的记录为止，或到文件末尾。</li>
</ul>
<p><a name="awk14"></a><br />
<h2>14. awk编程</h2>
<p><a name="awk1401"></a><br />
<h3>14.1. 变量</h3>
<ul>
<li>在awk中，变量不需要定义就可以直接使用，变量类型可以是数字或字符串。</li>
<li>赋值格式：Variable = expression，如$ awk &#8216;$1 ~/test/{count = $2 + $3; print count}&#8217; test,上式的作用是,awk先扫描第一个域，一旦test匹配，就把第二个域的值加上第三个域的值，并把结果赋值给变量count，最后打印出来。</li>
<li>awk 可以在命令行中给变量赋值，然后将这个变量传输给awk脚本。如$ awk -F: -f awkscript month=4 year=2004 test，上式的month和year都是自定义变量，分别被赋值为4和2004。在awk脚本中，这些变量使用起来就象是在脚本中建立的一样。注意，如果参数前面出现test，那么在BEGIN语句中的变量就不能被使用。</li>
<li>域变量也可被赋值和修改，如$ awk &#8216;{$2 = 100 + $1; print }&#8217; test,上式表示，如果第二个域不存在，awk将计算表达式100加$1的值，并将其赋值给$2，如果第二个域存在，则用表达式的值覆盖$2原来的值。再例如：$ awk &#8216;$1 == &#8220;root&#8221;{$1 =&#8221;test&#8221;;print}&#8217;</li>
<p> test，如果第一个域的值是“root”，则把它赋值为“test”，注意，字符串一定要用双引号。</li>
<li>内建变量的使用。变量列表在前面已列出，现在举个例子说明一下。$ awk -F: &#8216;{IGNORECASE=1; $1 == &#8220;MARY&#8221;{print NR,$1,$2,$NF}&#8217;test，把IGNORECASE设为1代表忽略大小写，打印第一个域是mary的记录数、第一个域、第二个域和最后一个域。</li>
</ul>
<p><a name="awk1402"></a><br />
<h3>14.2. BEGIN模块</h3>
<p>BEGIN 模块后紧跟着动作块，这个动作块在awk处理任何输入文件之前执行。所以它可以在没有任何输入的情况下进行测试。它通常用来改变内建变量的值，如OFS, RS和FS等，以及打印标题。如：$ awk &#8216;BEGIN{FS=&#8221;:&#8221;; OFS=&#8221;\t&#8221;; ORS=&#8221;\n\n&#8221;}{print $1,$2,$3} test。上式表示，在处理输入文件以前，域分隔符(FS)被设为冒号，输出文件分隔符(OFS)被设置为制表符，输出记录分隔符(ORS)被设置为两个换行符。$ awk &#8216;BEGIN{print &#8220;TITLE TEST&#8221;}只打印标题。</p>
<p><a name="awk1403"></a><br />
<h3>14.3. END模块</h3>
<p>END不匹配任何的输入文件，但是执行动作块中的所有动作，它在整个输入文件处理完成后被执行。如$ awk &#8216;END{print &#8220;The number of records is&#8221; NR}&#8217; test，上式将打印所有被处理的记录数。</p>
<p><a name="awk1404"></a><br />
<h3>14.4. 重定向和管道</h3>
<ul>
<li>awk 可使用shell的重定向符进行重定向输出，如：$ awk &#8216;$1 = 100 {print $1 > &#8220;output_file&#8221; }&#8217; test。上式表示如果第一个域的值等于100，则把它输出到output_file中。也可以用>>来重定向输出，但不清空文件，只做追加操作。</li>
<li>输出重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容，并给NF,NR和FNR等内建变量赋值。如果得到一条记录，getline函数返回1，如果到达文件的末尾就返回0，如果出现错误，例如打开文件失败，就返回-1。如：
<ul>
&nbsp;&nbsp;&nbsp;&nbsp;
<li>$ awk &#8216;BEGIN{ &#8220;date&#8221; | getline d; print d}&#8217; test。执行linux的date命令，并通过管道输出给getline，然后再把输出赋值给自定义变量d，并打印它。</li>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
<li>$ awk &#8216;BEGIN{&#8220;date&#8221; | getline d; split(d,mon); print mon[2]}&#8217; test。执行shell的date命令，并通过管道输出给getline，然后getline从管道中读取并将输入赋值给d，split函数把变量d转化成数组mon，然后打印数组mon的第二个元素。</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;$ awk &#8216;BEGIN{while( &#8220;ls&#8221; | getline) print}&#8217;，命令ls的输出传递给geline作为输入，循环使getline从ls的输出中读取一行，并把它打印到屏幕。这里没有输入文件，因为 BEGIN块在打开输入文件前执行，所以可以忽略输入文件。</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;$ awk &#8216;BEGIN{printf &#8220;What is your name?&#8221;; getline name < "/dev/tty" } $1 ~name {print "Found" name on line ", NR "."} END{print "See you," name "."} test。在屏幕上打印”What is your name?",并等待用户应答。当一行输入完毕后，getline函数从终端接收该行输入，并把它储存在自定义变量name中。如果第一个域匹配变量 name的值，print函数就被执行，END块打印See you和name的值。</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;$ awk &#8216;BEGIN{while (getline < "/etc/passwd" > 0) lc++; print lc}&#8217;。awk将逐行读取文件/etc/passwd的内容，在到达文件末尾前，计数器lc一直增加，当到末尾时，打印lc的值。注意，如果文件不存在，getline返回-1，如果到达文件的末尾就返回0，如果读到一行，就返回1，所以命令 while (getline < "/etc/passwd")在文件不存在的情况下将陷入无限循环，因为返回-1表示逻辑真。</li>
</ul>
</li>
<li> 可以在awk中打开一个管道，且同一时刻只能有一个管道存在。通过close()可关闭管道。如：$ awk &#8216;{print $1, $2 | &#8220;sort&#8221; }&#8217; test END {close(&#8220;sort&#8221;)}。awd把print语句的输出通过管道作为linux命令sort的输入,END块执行关闭管道操作。</li>
<li>system函数可以在awk中执行linux的命令。如：$ awk &#8216;BEGIN{system(&#8220;clear&#8221;)&#8217;。</li>
<li>fflush函数用以刷新输出缓冲区，如果没有参数，就刷新标准输出的缓冲区，如果以空字符串为参数，如fflush(&#8220;&#8221;),则刷新所有文件和管道的输出缓冲区。</li>
</ul>
<p><a name="awk1405"></a><br />
<h3>14.5. 条件语句</h3>
<p>awk中的条件语句是从C语言中借鉴过来的，可控制程序的流程。</p>
<h4>14.5.1. if语句</h4>
<p>格式：
<div class="hl-surround"><div class="hl-main">{if (expression){<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div></div>
<p>$ awk &#8216;{if ($1 <$2) print $2 "too high"}' test。如果第一个域小于第二个域则打印。<br />
$ awk '{if ($1 < $2) {count++; print "ok"}}' test.如果第一个域小于第二个域，则count加一，并打印ok。</p>
<h4>14.5.2. if/else语句，用于双重判断。</h4>
<p>格式：
<div class="hl-surround"><div class="hl-main">{if (expression){<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else{<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div></div>
<p>$ awk &#8216;{if ($1 > 100) print $1 &#8220;bad&#8221; ; else print &#8220;ok&#8221;}&#8217; test。如果$1大于100则打印$1 bad,否则打印ok。<br />
$ awk &#8216;{if ($1 > 100){ count++; print $1} else {count&#8211;; print $2}&#8217; test。如果$1大于100，则count加一，并打印$1，否则count减一，并打印$1。</p>
<h4>14.5.3. if/else else if语句，用于多重判断。</h4>
<p>格式：
<div class="hl-surround"><div class="hl-main">{if (expression){<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else if (expression){<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else if (expression){<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else {<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; statement; statement; ...<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div></div>
<p><a name="awk1406"></a><br />
<h3>14.6. 循环</h3>
<ul>
<li>awk有三种循环:while循环；for循环；special for循环。</li>
<li> $ awk &#8216;{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test。变量的初始值为1，若i小于可等于NF(记录中域的个数),则执行打印语句，且i增加1。直到i的值大于NF.</li>
<li>$ awk &#8216;{for (i = 1; i<NF; i++) print NF,$i}' test。作用同上。</li>
<li>breadkcontinue语句。break用于在满足条件的情况下跳出循环；continue用于在满足条件的情况下忽略后面的语句，直接返回循环的顶端。如：
<div class="hl-surround"><div class="hl-main">{for ( x=3; x&lt;=NF; x++) <br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($x&lt;0){print &quot;Bottomed out!&quot;; break}}<br />&nbsp;&nbsp; &nbsp; &nbsp;{for ( x=3; x&lt;=NF; x++)<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ($x==0){print &quot;Get next item&quot;; continue}}</div></div>
</li>
<li>next语句从输入文件中读取一行，然后从头开始执行awk脚本。如：
<div class="hl-surround"><div class="hl-main">{if ($1 ~/test/){next}<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else {print}<br />&nbsp;&nbsp; &nbsp; &nbsp;}</div></div>
</li>
<li>exit语句用于结束awk程序，但不会略过END块。退出状态为0代表成功，非零值表示出错。</li>
</ul>
<p><a name="awk1407"></a><br />
<h3>14.7. 数组</h3>
<p>awk中的数组的下标可以是数字和字母，称为关联数组。</p>
<h4>14.7.1. 下标与关联数组</h4>
<ul>
<li>用变量作为数组下标。如：$ awk {name[x++]=$2};END{for(i=0;i<NR;i++) print i,name[i]}' test。数组name中的下标是一个自定义变量x，awk初始化x的值为0，在每次使用后增加1。第二个域的值被赋给name数组的各个元素。在END 模块中，for循环被用于循环整个数组，从下标为0的元素开始，打印那些存储在数组中的值。因为下标是关健字，所以它不一定从0开始，可以从任何值开始。</li>
<li>special for循环用于读取关联数组中的元素。格式如下：
<div class="hl-surround"><div class="hl-main">{for (item in arrayname){<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print arrayname[item]<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp;}</div></div>
</li>
<li>$ awk &#8216;/^tom/{name[NR]=$1}; END{for(i in name){print name[i]}}&#8217; test。打印有值的数组元素。打印的顺序是随机的。</li>
<li>用字符串作为下标。如：count["test"]</li>
<li>用域值作为数组的下标。一种新的for循环方式，for (index_value in array) statement。如:$ awk &#8216;{count[$1]++} END{for(name in count) print name,count[name]}&#8217; test。该语句将打印$1中字符串出现的次数。它首先以第一个域作数组count的下标，第一个域变化，索引就变化。</li>
<li>delete 函数用于删除数组元素。如：$ awk &#8216;{line[x++]=$1} END{for(x in line) delete(line[x])}&#8217; test。分配给数组line的是第一个域的值，所有记录处理完成后，special for循环将删除每一个元素。</li>
</ul>
<p><a name="awk1408"></a><br />
<h3>14.8. awk的内建函数</h3>
<h4>14.8.1. 字符串函数</h4>
<ul>
<li>sub函数匹配记录中最大、最靠左边的子字符串的正则表达式，并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。格式如下：
<div class="hl-surround"><div class="hl-main">sub (regular expression, substitution string):<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sub (regular expression, substitution string, target string)</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ sub(/test/, &quot;mytest&quot;); print }' testfile<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$ awk '{ sub(/test/, &quot;mytest&quot;); $1}; print }' testfile</div></div>
<p>      第一个例子在整个记录中匹配，替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub<br />
      第二个例子在整个记录的第一个域中进行匹配，替换只发生在第一次匹配发生的时候。</li>
<li>gsub函数作用如sub，但它在整个文档中进行匹配。格式如下：
<div class="hl-surround"><div class="hl-main">gsub (regular expression, substitution string)<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gsub (regular expression, substitution string, target string)</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ gsub(/test/, &quot;mytest&quot;); print }' testfile<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$ awk '{ gsub(/test/, &quot;mytest&quot;), $1 }; print }' testfile</div></div>
<p>      第一个例子在整个文档中匹配test，匹配的都被替换成mytest。<br />
      第二个例子在整个文档的第一个域中匹配，所有匹配的都被替换成mytest。</li>
<li>index函数返回子字符串第一次被匹配的位置，偏移量从位置1开始。格式如下：
<div class="hl-surround"><div class="hl-main">index(string, substring)</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ print index(&quot;test&quot;, &quot;mytest&quot;) }' testfile</div></div>
<p>      实例返回test在mytest的位置，结果应该是3。</li>
<li>length函数返回记录的字符数。格式如下：
<div class="hl-surround"><div class="hl-main">length( string )<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;length</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ print length( &quot;test&quot; ) }' <br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$ awk '{ print length }' testfile</div></div>
<p>      第一个实例返回test字符串的长度。<br />
      第二个实例返回testfile文件中第条记录的字符数。</li>
<li>substr函数返回从位置1开始的子字符串，如果指定长度超过实际长度，就返回整个字符串。格式如下：
<div class="hl-surround"><div class="hl-main">substr( string, starting position )<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;substr( string, starting position, length of string )</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ print substr( &quot;hello world&quot;, 7,11 ) }'</div></div>
<p>      上例截取了world子字符串。</li>
<li>match函数返回在字符串中正则表达式位置的索引，如果找不到指定的正则表达式则返回0。match函数会设置内建变量RSTART为字符串中子字符串的开始位置，RLENGTH为到子字符串末尾的字符个数。substr可利于这些变量来截取字符串。函数格式如下：
<div class="hl-surround"><div class="hl-main">match( string, regular expression )</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{start=match(&quot;this is a test&quot;,/[a-z]+$/); print start}'<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$ awk '{start=match(&quot;this is a test&quot;,/[a-z]+$/); print start, RSTART, RLENGTH }'</div></div>
<p>      第一个实例打印以连续小写字符结尾的开始位置，这里是11。<br />
      第二个实例还打印RSTART和RLENGTH变量，这里是11(start)，11(RSTART)，4(RLENGTH)。</li>
<li>toupper和tolower函数可用于字符串大小间的转换，该功能只在gawk中有效。格式如下：
<div class="hl-surround"><div class="hl-main">toupper( string )<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tolower( string )</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ print toupper(&quot;test&quot;), tolower(&quot;TEST&quot;) }'</div></div>
<li>split函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供，则按当前FS值进行分割。格式如下：
<div class="hl-surround"><div class="hl-main">split( string, array, field separator )<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;split( string, array )</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ split( &quot;20:18:00&quot;, time, &quot;:&quot; ); print time[2] }'</div></div>
<p>      上例把时间按冒号分割到time数组内，并显示第二个数组元素18。</li>
</ul>
<h4>14.8.2. 时间函数</h4>
<ul>
<li>systime函数返回从1970年1月1日开始到当前时间(不计闰年)的整秒数。格式如下：
<div class="hl-surround"><div class="hl-main">systime()</div></div>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ now = systime(); print now }'</div></div>
</li>
<li>strftime函数使用C库中的strftime函数格式化时间。格式如下：
<div class="hl-surround"><div class="hl-main">systime( [format specification][,timestamp] )</div></div>
</li>
</ul>
<p>      Table 3. 日期和时间格式说明符<br />
<table border=1>
<tr>
<th>格式</th>
<th>描述</th>
</tr>
<tr>
<td>%a</td>
<td>星期几的缩写(Sun)</td>
</tr>
<tr>
<td>%A</td>
<td>星期几的完整写法(Sunday)</td>
</tr>
<tr>
<td>%b</td>
<td>月名的缩写(Oct)</td>
</tr>
<tr>
<td>%B</td>
<td>月名的完整写法(October)</td>
</tr>
<tr>
<td>%c</td>
<td>本地日期和时间</td>
</tr>
<tr>
<td>%d</td>
<td>十进制日期</td>
</tr>
<tr>
<td>%D</td>
<td>日期 08/20/99</td>
</tr>
<tr>
<td>%e</td>
<td>日期，如果只有一位会补上一个空格</td>
</tr>
<tr>
<td>%H</td>
<td>用十进制表示24小时格式的小时</td>
</tr>
<tr>
<td>%I</td>
<td>用十进制表示12小时格式的小时</td>
</tr>
<tr>
<td>%j</td>
<td>从1月1日起一年中的第几天</td>
</tr>
<tr>
<td>%m</td>
<td>十进制表示的月份</td>
</tr>
<tr>
<td>%M</td>
<td>十进制表示的分钟</td>
</tr>
<tr>
<td>%p</td>
<td>12小时表示法(AM/PM)</td>
</tr>
<tr>
<td>%S</td>
<td>十进制表示的秒</td>
</tr>
<tr>
<td>%U</td>
<td>十进制表示的一年中的第几个星期(星期天作为一个星期的开始)</td>
</tr>
<tr>
<td>%w</td>
<td>十进制表示的星期几(星期天是0)</td>
</tr>
<tr>
<td>%W</td>
<td>十进制表示的一年中的第几个星期(星期一作为一个星期的开始)</td>
</tr>
<tr>
<td>%x</td>
<td>重新设置本地日期(08/20/99)</td>
</tr>
<tr>
<td>%X</td>
<td>重新设置本地时间(12：00：00)</td>
</tr>
<tr>
<td>%y</td>
<td>两位数字表示的年(99)</td>
</tr>
<tr>
<td>%Y</td>
<td>当前月份</td>
</tr>
<tr>
<td>%Z</td>
<td>时区(PDT)</td>
</tr>
<tr>
<td>%%</td>
<td>百分号(%)</td>
</tr>
</table>
<p>      实例：
<div class="hl-surround"><div class="hl-main">$ awk '{ now=strftime( &quot;%D&quot;, systime() ); print now }'<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$ awk '{ now=strftime(&quot;%m/%d/%y&quot;); print now }'</div></div>
<h4>14.8.3. 内建数学函数</h4>
<p>Table 4.<br />
<table border=1>
<tr>
<th>函数名称</th>
<th>返回值</th>
</tr>
<tr>
<td>atan2(x,y)</td>
<td>y,x范围内的余切</td>
</tr>
<tr>
<td>cos(x)</td>
<td>余弦函数</td>
</tr>
<tr>
<td>exp(x)</td>
<td>求幂</td>
</tr>
<tr>
<td>int(x)</td>
<td>取整</td>
</tr>
<tr>
<td>log(x)</td>
<td>自然对数</td>
</tr>
<tr>
<td>rand()</td>
<td>随机数</td>
</tr>
<tr>
<td>sin(x)</td>
<td>正弦</td>
</tr>
<tr>
<td>sqrt(x)</td>
<td>平方根</td>
</tr>
<tr>
<td>srand(x)</td>
<td>x是rand()函数的种子</td>
</tr>
<tr>
<td>int(x)</td>
<td>取整，过程没有舍入</td>
</tr>
<tr>
<td>rand()</td>
<td>产生一个大于等于0而小于1的随机数</td>
</tr>
</table>
<h4>14.8.4. 自定义函数</h4>
<p>在awk中还可自定义函数，格式如下：
<div class="hl-surround"><div class="hl-main">function name ( parameter, parameter, parameter, ... ) {<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;statements<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return expression&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # the return statement and expression are optional<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div></div>
<p><a name="awk15"></a><br />
<h2>115. How-to</h2>
<p>      如何把一行竖排的数据转换成横排？
<div class="hl-surround"><div class="hl-main">awk '{printf(&quot;%s,&quot;,$1)}' filename</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/08/20/how-to-use-awk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>在CentOS上安装配置heartbeat</title>
		<link>http://blog.myhnet.cn/2010/08/15/install-and-configure-heartbeat-in-centos/</link>
		<comments>http://blog.myhnet.cn/2010/08/15/install-and-configure-heartbeat-in-centos/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 10:32:07 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[安装配置]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[热备]]></category>
		<category><![CDATA[高可用]]></category>
		<category><![CDATA[glue]]></category>
		<category><![CDATA[ha]]></category>
		<category><![CDATA[heartbeat]]></category>
		<category><![CDATA[libplumb.so]]></category>
		<category><![CDATA[main.c:64: warning: function declaration isn't a prototype]]></category>
		<category><![CDATA[uuid_parse]]></category>
		<category><![CDATA[xinclude]]></category>
		<category><![CDATA[主备]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1035</guid>
		<description><![CDATA[Heartbeat提供了高可用集群最基本的功能，例如，节点间的内部通信方式、集群合作管理机制、监控工具和失效切换功能等。但是Heartbeat仅仅是个HA软件，它仅能完成心跳监控和资源接管，不会监视它控制的资源或应用程序。要监控资源和应用程序是否运行正常，必须使用第三方的插件，例如ipfail、Mon和Ldirector等。Heartbeat自身包含了几个插件，分别是ipfail、Stonith和 Ldirectord。 在家闲着无事，就简单的测试了一下heartbeat，没怎么深入测试，所以本文只会告诉你怎么让heartbeat跑起来，不涉及服务。 安装heartbeat不是个简单的事情，很多文章说可以直接用yum来安装，但我从碟上的安装源以及rpmforge的源中都没有找到heartbeata的包(如果你知道可以告诉我哪个源里面可以直接安装heartbeat)，所以我还是从官方网站下载了三个包来进行编译。 编译的顺序是：先Cluster Glue, 再Resource Agents，然后才是Heartbeat。 这个编译可不是个简单的事，它可耗费了我不少时间。首先要安装autoconf, automake,pkgconfig,libxslt-devel等包。configure都没有大问题，都不在话下，都有明确的提示。 第一个不好解决的错误就是 ./.libs/libplumb.so: undefined reference to `uuid_parse'./.libs/libplumb.so: undefined reference to `uuid_generate'./.libs/libplumb.so: undefined reference to `uuid_copy'./.libs/libplumb.so: undefined reference to `uuid_is_null'./.libs/libplumb.so: undefined reference to `uuid_unparse'./.libs/libplumb.so: undefined reference to `uuid_clear'./.libs/libplumb.so: undefined reference to `uuid_compare'collect2: ld returned 1 exit statusgmake[2]: *** [ipctest] Error 1gmake[2]: Leaving directory `/root/Reusable-Cluster-Components-glue-1.0.6/lib/clplumbing'gmake[1]: *** [all-recursive] Error [...]]]></description>
			<content:encoded><![CDATA[<p>Heartbeat提供了高可用集群最基本的功能，例如，节点间的内部通信方式、集群合作管理机制、监控工具和失效切换功能等。但是Heartbeat仅仅是个HA软件，它仅能完成心跳监控和资源接管，不会监视它控制的资源或应用程序。要监控资源和应用程序是否运行正常，必须使用第三方的插件，例如ipfail、Mon和Ldirector等。Heartbeat自身包含了几个插件，分别是ipfail、Stonith和 Ldirectord。</p>
<p>在家闲着无事，就简单的测试了一下heartbeat，没怎么深入测试，所以本文只会告诉你怎么让heartbeat跑起来，不涉及服务。</p>
<p>安装heartbeat不是个简单的事情，很多文章说可以直接用yum来安装，但我从碟上的安装源以及rpmforge的源中都没有找到heartbeata的包(如果你知道可以告诉我哪个源里面可以直接安装heartbeat)，所以我还是从官方网站下载了三个包来进行编译。</p>
<p>编译的顺序是：先Cluster Glue, 再Resource Agents，然后才是Heartbeat。</p>
<p>这个编译可不是个简单的事，它可耗费了我不少时间。首先要安装autoconf, automake,pkgconfig,libxslt-devel等包。configure都没有大问题，都不在话下，都有明确的提示。</p>
<p>第一个不好解决的错误就是
<div class="hl-surround"><div class="hl-main">./.libs/libplumb.so: undefined reference to `uuid_parse'<br />./.libs/libplumb.so: undefined reference to `uuid_generate'<br />./.libs/libplumb.so: undefined reference to `uuid_copy'<br />./.libs/libplumb.so: undefined reference to `uuid_is_null'<br />./.libs/libplumb.so: undefined reference to `uuid_unparse'<br />./.libs/libplumb.so: undefined reference to `uuid_clear'<br />./.libs/libplumb.so: undefined reference to `uuid_compare'<br />collect2: ld returned 1 exit status<br />gmake[2]: *** [ipctest] Error 1<br />gmake[2]: Leaving directory `/root/Reusable-Cluster-Components-glue-1.0.6/lib/clplumbing'<br />gmake[1]: *** [all-recursive] Error 1<br />gmake[1]: Leaving directory `/root/Reusable-Cluster-Components-glue-1.0.6/lib'<br />make: *** [all-recursive] Error 1</div></div>
<p>这个差不多能看出来是uuid方面的包的故障，所以我一开始就想去安装一个libuuid-devel的包，在这个上面消耗了不少时间。但最后通过google与linux-ha的maillist得到了提示，总算是把这个问题给解决了。解决方法其实很简单，只要在configure时在后面加上：
<div class="hl-surround"><div class="hl-main">LIBS='/lib/libuuid.so.1'</div></div>
<p>这个问题在对三个包进行make的时候都会出现类似的错误，所以这个解决方法在make三个包时都要用到。还要提到的是，在对Heartbeat进行configure的时候，最好用他推荐的ConfigureMe而不要用configure。</p>
<p>第二个比较麻烦的问题也是在make时碰到的，不过只是在make Cluster Glue才有：
<div class="hl-surround"><div class="hl-main">cc1: warnings being treated as errors&nbsp; <br />main.c:64: warning: function declaration isn't a prototype<br />main.c:78: warning: function declaration isn't a prototype<br />gmake[2]: *** [main.o] Error 1<br />gmake[2]: Leaving directory<br />`/root/Reusable-Cluster-Components-glue-1.0.6/lib/stonith'<br />gmake[1]: *** [all-recursive] Error 1<br />gmake[1]: Leaving directory `/root/Reusable-Cluster-Components-glue-1.0.6/lib'<br />make: *** [all-recursive] Error 1<br />error: Bad exit status from /var/tmp/rpm-tmp.55884 (%build)</div></div>
<p>这个问题我都估计是Cluster Glue的一个bug，产生的原因与解决的方法实在是太鬼异了。从错误信息上来看，这是main.c文件里面的函数定义错误，解决办法就是将其version函数从stonith子目录下面的main.c文件里面删除（我对编程不懂，不过改名是没用的）。</p>
<p>打开stonith子目录下面的main.c。<br />
1、找到其64行，将其注释掉。<br />
2、找到其76到81行全部注释掉。<br />
3、找到其390行，将其注释，或者换成
<div class="hl-surround"><div class="hl-main">case 'V':&nbsp; &nbsp; &nbsp;printf(&quot;stonith: %s (%s)\n&quot;, GLUE_VERSION, GLUE_BUILD_VERSION);</div></div>
<p>这之后来说应该都会是一帆风顺的了，当然你也有可能在make install Heartbeat碰到这个问题：
<div class="hl-surround"><div class="hl-main">gmake[1]: Entering directory `/root/Heartbeat-3-0-STABLE-3.0.3/doc'<br />\<br />	--xinclude \<br />	http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl heartbeat.xml<br />gmake[1]: --xinclude: Command not found<br />gmake[1]: *** [heartbeat.8] Error 127<br />gmake[1]: Leaving directory `/root/Heartbeat-3-0-STABLE-3.0.3/doc'<br />make: *** [all-recursive] Error 1</div></div>
<p>这个就是因为你没有安装前面我说的那个libxslt-devel包了。安装好之后就可以。</p>
<p>顺便说一句，在make install Heartbeat的时候，这个&#8211;xinclude这些xml文件时可能要耗大量的时间，有时候可能由于网络原因还会报错，这个时候只要再来几次基本上也就没有问题了。</p>
<p>接下来就是重头戏，配置heartbeat了。<br />
heartbeat的配置文件有两个位置/etc/ha.d与/usr/etc/ha.d，由于没有仔细去读/etc/init.d/heartbeat，导致一会儿报这里找不到一个文件一会儿那里找不到一个文件，我干脆就所/usr/etc/ha.d下面的内容全部copy到/etc/ha.d里面，再删掉/usr/etc/ha.d，然后做一个软链接指向/etc/ha.d。整个世界终于清醒了。</p>
<p>然后就是/etc/ha.d/ha.cf文件了，这里我就提供我的ha.cf文件，然后简单的解释一下：
<div class="hl-surround"><div class="hl-main">debugfile /var/log/ha-debug<br />logfile	/var/log/ha-log<br />logfacility	local0<br />keepalive 2<br />deadtime 30<br />warntime 10<br />initdead 60<br />udpport	694<br />bcast	eth0<br />#mcast eth1 225.0.0.1 694 1 0<br />#ucast eth0 192.168.0.1<br />auto_failback on<br />watchdog /dev/watchdog<br />node node1<br />node node2<br />ping 172.16.217.1<br />respawn hacluster /usr/lib/heartbeat/ipfail<br />compression zlib</div></div>
<p>debugfile与logfile是定义日志文件的位置，如果两个都没有定义，默认会写入/var/log/message。<br />
keepalive指定心跳间隔时间即每隔多少秒钟在eth0上发送一次广播。<br />
deadtime指定若备用节点在多少秒内没有收到主节点的心跳信号，则立即接管主节点的服务资源。<br />
warntime指定心跳延迟的时间为N秒。当N秒钟内备份节点不能接收到主节点的心跳信号时，就会往日志中写入一个警告日志，但此时不会切换服务<br />
initdead在某些系统上，系统启动或重启之后需要经过一段时间网络才能正常工作，该选项用于解决这种情况产生的时间间隔。取值至少为deadtime的两倍<br />
bcast、mcast与ucast都是定义心跳的，三个任选一个即可。bcast是直接定义使用设备，mcast使用多播，ucast是单播。<br />
auto_failback指定主机恢复后是否自动切换回主机服务。<br />
node后面一定要接uname -n的结果。<br />
ping与respawn hacluster /usr/lib/heartbeat/ipfail用来测试网络连接，ping后面接外网网关或者其他可靠的设备的IP，如果这个IP一旦ping不通了（意味该机的外网down了），则利用respawn调用/usr/lib/heartbeat/ipfail来主动进行切换。</p>
<p>其他的各项定义，大家自己man ha.cf看吧，我也没时间去管那么多了。</p>
<p>接下来就是/etc/ha.d/authkeys。<br />
authkeys文件用于设定Heartbeat的认证方式，共有3种可用的认证方式，即crc、 md5和sha1。3种认证方式的安全性依次提高，但是占用的系统资源也依次增加。如果Heartbeat集群运行在安全的网络上，可以使用crc方式；如果HA每个节点的硬件配置很高，建议使用sha1，这种认证方式安全级别最高；如果是处于网络安全和系统资源之间，可以使用md5认证方式。<br />
我这里直接用crc，只反注释了下面这两行：
<div class="hl-surround"><div class="hl-main"># auth 1&nbsp; <br /># 1 crc</div></div>
<p>最后就是/etc/ha.d/haresources<br />
这个文件里面最有文章，大家可以去参考相关文章，我这里只解释我的（最简单的）
<div class="hl-surround"><div class="hl-main">node1 172.16.217.200 httpd</div></div>
<p>其中的node1定义是主机（active host），172.16.217.200是VIP（虚拟IP，也就是真正对外提供服务的IP），httpd也就是httpd服务。</p>
<p>之后，大家就尽情测试吧。呵呵</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/08/15/install-and-configure-heartbeat-in-centos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XBMC中文设置</title>
		<link>http://blog.myhnet.cn/2010/08/08/xbmc%e4%b8%ad%e6%96%87%e8%ae%be%e7%bd%ae/</link>
		<comments>http://blog.myhnet.cn/2010/08/08/xbmc%e4%b8%ad%e6%96%87%e8%ae%be%e7%bd%ae/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 00:34:59 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[others]]></category>
		<category><![CDATA[linux媒体播放]]></category>
		<category><![CDATA[media center]]></category>
		<category><![CDATA[xbmc]]></category>
		<category><![CDATA[媒体中心]]></category>
		<category><![CDATA[播放器]]></category>
		<category><![CDATA[中文]]></category>
		<category><![CDATA[中文支持]]></category>
		<category><![CDATA[中文乱码]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1033</guid>
		<description><![CDATA[昨日经大M同学推荐装了一个XBMC，看起来效果还不错，用在电视上应该挺方便的。 但xbmc虽然支持中文，默认却无中文字体。我们就去 /usr/share/xbmc/media/Fonts 里面，把arial.ttf文件替换掉。下面这个命令是直接用系统自带的文驿泉的字体替换了 sudo cp /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc /usr/share/xbmc/media/Fonts/arial.ttf 再提一句，原来版本如果字体体积过大，在播放视频时会出现退出重启XBMC的情况。现在已经修复这个bug了，很好！ （1）启动XBMC后，在主界面选择Settings，进入系统设置； （2）在系统设置画面选择Appearance，进入用户界面设置； （3）在屏幕左边选择Look and Feel，然后把Skin Fonts项目设置成arial （4）在屏幕左边选择Region，然后把Language项目设置成Chinese(Simple) （5）设置“字符集”为“Chinese Simplified(GBK)”]]></description>
			<content:encoded><![CDATA[<p>昨日经大M同学推荐装了一个XBMC，看起来效果还不错，用在电视上应该挺方便的。</p>
<p>但xbmc虽然支持中文，默认却无中文字体。我们就去 /usr/share/xbmc/media/Fonts 里面，把arial.ttf文件替换掉。下面这个命令是直接用系统自带的文驿泉的字体替换了</p>
<div class="hl-surround"><div class="hl-main">sudo cp /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc /usr/share/xbmc/media/Fonts/arial.ttf</div></div>
<p>再提一句，原来版本如果字体体积过大，在播放视频时会出现退出重启XBMC的情况。现在已经修复这个bug了，很好！</p>
<p>（1）启动XBMC后，在主界面选择Settings，进入系统设置；<br />
（2）在系统设置画面选择Appearance，进入用户界面设置；<br />
（3）在屏幕左边选择Look and Feel，然后把Skin Fonts项目设置成arial<br />
（4）在屏幕左边选择Region，然后把Language项目设置成Chinese(Simple)<br />
（5）设置“字符集”为“Chinese Simplified(GBK)”</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/08/08/xbmc%e4%b8%ad%e6%96%87%e8%ae%be%e7%bd%ae/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux下用tar来进行增量备份</title>
		<link>http://blog.myhnet.cn/2010/08/06/perform-a-incremental-backup-with-tar-in-linux/</link>
		<comments>http://blog.myhnet.cn/2010/08/06/perform-a-incremental-backup-with-tar-in-linux/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 12:51:53 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[incremental backup]]></category>
		<category><![CDATA[tar]]></category>
		<category><![CDATA[tar -g]]></category>
		<category><![CDATA[增量备份]]></category>
		<category><![CDATA[备份]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1026</guid>
		<description><![CDATA[近来无聊，博客又好久没有更新了，权且来说说linux下面的文件备份吧。 备份无非就是全量备份与增量备份。linux下面的全量备份自然不用说，很多命令与软件都能实现；增量备份相对来说软件就要少些，我常用的就是rsync与tar。 rsync与tar相比，rsync的优点在于可以异机备份，缺点在用不能对文件进行压缩。tar的优点就是可以调用bzip2或者gzip进行压缩，但是只限于本机备份。rsync我这里就不多讲了，今天就来说说tar吧 开题不说闲话，其他参数格式我都不说了，说说我们今天要用的参数格式： tar -g /path/to/info_file -zcvf /path/to/files_need_backup 在这里对info_file info_file是一个纯文本文件，以UNIX时间记录备份的时间戳。这个文件一般是第一次全备时自动创建，也可以手动创建。如果你手动创建这个文件，那tar就只会备份在这个时间戳之后修改过的文件，所以严格意义上来说，tar的增量备份并不能算做是增量备份，而只是按时间戳备份而已。这点远远比不上rsync。 ok，了解了一下概念，我们正式开始： $ mkdir dest$ touch dest/{1,2,3}$ tar -g /tmp/timestamp -zcvf backup0.tgz dest/dest/dest/1dest/2dest/3$ cat /tmp/timestamp 1281096816 由于/tmp/timestamp原来是不存在的，所以这次备份下来的backup0.tgz就是一个全备份文件。备份之后的timestamp文件内容是1281096816。 然后我们继续。这个时候就要记得info_file要继续用上次全备文件之后文件： $ tar -g /tmp/timestamp -zcvf backup1.tgz dest/dest/dest/4dest/5dest/6$ cat /tmp/timestamp 1281097104 我们可以看到，这次生成的backup1.tgz并没有备份还在dest目录下面的文件1, 2, 3，而只备份了新生成的文件4, 5, 6。 然后，我们再来一个测试 $ touch dest/{7,8}$ date +%s &#62; /tmp/timestamp$ touch dest/9$ tar -g [...]]]></description>
			<content:encoded><![CDATA[<p>近来无聊，博客又好久没有更新了，权且来说说linux下面的文件备份吧。</p>
<p>备份无非就是全量备份与增量备份。linux下面的全量备份自然不用说，很多命令与软件都能实现；增量备份相对来说软件就要少些，我常用的就是rsync与tar。</p>
<p>rsync与tar相比，rsync的优点在于可以异机备份，缺点在用不能对文件进行压缩。tar的优点就是可以调用bzip2或者gzip进行压缩，但是只限于本机备份。rsync我这里就不多讲了，今天就来说说tar吧</p>
<p>开题不说闲话，其他参数格式我都不说了，说说我们今天要用的参数格式：</p>
<div class="hl-surround"><div class="hl-main">tar -g /path/to/info_file -zcvf /path/to/files_need_backup</div></div>
<p>在这里对info_file<br />
info_file是一个纯文本文件，以UNIX时间记录备份的时间戳。这个文件一般是第一次全备时自动创建，也可以手动创建。如果你手动创建这个文件，那tar就只会备份在这个时间戳之后修改过的文件，所以严格意义上来说，tar的增量备份并不能算做是增量备份，而只是按时间戳备份而已。这点远远比不上rsync。</p>
<p>ok，了解了一下概念，我们正式开始：</p>
<div class="hl-surround"><div class="hl-main">$ mkdir dest<br />$ touch dest/{1,2,3}<br />$ tar -g /tmp/timestamp -zcvf backup0.tgz dest/<br />dest/<br />dest/1<br />dest/2<br />dest/3<br />$ cat /tmp/timestamp <br />1281096816</div></div>
<p>由于/tmp/timestamp原来是不存在的，所以这次备份下来的backup0.tgz就是一个全备份文件。备份之后的timestamp文件内容是1281096816。</p>
<p>然后我们继续。这个时候就要记得info_file要继续用上次全备文件之后文件：</p>
<div class="hl-surround"><div class="hl-main">$ tar -g /tmp/timestamp -zcvf backup1.tgz dest/<br />dest/<br />dest/4<br />dest/5<br />dest/6<br />$ cat /tmp/timestamp <br />1281097104</div></div>
<p>我们可以看到，这次生成的backup1.tgz并没有备份还在dest目录下面的文件1, 2, 3，而只备份了新生成的文件4, 5, 6。</p>
<p>然后，我们再来一个测试</p>
<div class="hl-surround"><div class="hl-main">$ touch dest/{7,8}<br />$ date +%s &gt; /tmp/timestamp<br />$ touch dest/9<br />$ tar -g /tmp/timestamp -zcvf backup2.tgz dest/<br />dest/9<br />$ cat /tmp/timestamp <br />1281097553</div></div>
<p>我在创建文件7, 8之后，利用date命令手动刷新了一下info_file的内容，然后再创建了文件9，之后的备份，大家就可以很明显的看到，文件7, 8并没有被备份。</p>
<p>大家应该也就应该看出来了，这就存在一个问题，就是-g做增量备份时的这个info_file到底记录的是什么时刻的时间。大家可以通过实验得到，info_file的更新时间在在.tgz文件之后的，但究竟记录的时间是不是刚刚开始时间呢？</p>
<p>这个我们也可以通过一个小实验来得到：</p>
<div class="hl-surround"><div class="hl-main">$ for i in `seq 1 100`; do dd if=/dev/zero of=dest/test$i bs=1M count=10;done<br />$ date +%s &amp;&amp; tar -g /tmp/timestamp -zcf backup3.tgz dest &amp;&amp; cat /tmp/timestamp &amp;&amp; date +%s<br />1281098446<br />1281098523<br />1281098524</div></div>
<p>怎么样，很明显了吧。如果直接用这种方式备份的话，那么<strong><font color=red>从你备份开始到备份结束之间生成的文件是不会被备份的</font></strong>。</p>
<p>不过，这也难不倒聪明的你吧。嘿嘿。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/08/06/perform-a-incremental-backup-with-tar-in-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend Optimizer 3.3.3 is incompatible with XCache 1.2.2 in Unknown on line 0</title>
		<link>http://blog.myhnet.cn/2010/07/29/zend-optimizer-3-3-3-is-incompatible-with-xcache-1-2-2-in-unknown-on-line-0/</link>
		<comments>http://blog.myhnet.cn/2010/07/29/zend-optimizer-3-3-3-is-incompatible-with-xcache-1-2-2-in-unknown-on-line-0/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 16:00:23 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP & PW]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[optimizer]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php optimizing]]></category>
		<category><![CDATA[php优化]]></category>
		<category><![CDATA[ptimizing]]></category>
		<category><![CDATA[xcache]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1022</guid>
		<description><![CDATA[想在服务器上同时使用Zend Optimizer与Xcache时遇到的问题 PHP Fatal error: [Zend Optimizer] Zend Optimizer 3.3.3 is incompatible with XCache 1.2.2 in Unknown on line 0 原因： Zend主动蔽屏其他一些插件，xcache偏在其内 解决方法：把xcache的配置写在zend配置的前面即可 来源：http://xcache.lighttpd.net/ticket/200]]></description>
			<content:encoded><![CDATA[<p>想在服务器上同时使用Zend Optimizer与Xcache时遇到的问题</p>
<div class="hl-surround"><div class="hl-main">PHP Fatal error: [Zend Optimizer] Zend Optimizer 3.3.3 is incompatible with XCache 1.2.2 in Unknown on line 0</div></div>
<p>原因： Zend主动蔽屏其他一些插件，xcache偏在其内</p>
<p>解决方法：把xcache的配置写在zend配置的前面即可</p>
<p>来源：<a href="http://xcache.lighttpd.net/ticket/200" target=_blank>http://xcache.lighttpd.net/ticket/200</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/07/29/zend-optimizer-3-3-3-is-incompatible-with-xcache-1-2-2-in-unknown-on-line-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解决linux中sqlplus上下键显示历史sql语句</title>
		<link>http://blog.myhnet.cn/2010/07/28/how-to-roll-the-commands-from-history-in-sqlpus-under-linux/</link>
		<comments>http://blog.myhnet.cn/2010/07/28/how-to-roll-the-commands-from-history-in-sqlpus-under-linux/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 07:39:45 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[readline]]></category>
		<category><![CDATA[rlwrap]]></category>
		<category><![CDATA[sqlplus]]></category>
		<category><![CDATA[历史SQL]]></category>
		<category><![CDATA[历史命令]]></category>
		<category><![CDATA[命令翻滚]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1019</guid>
		<description><![CDATA[来源：http://www.boobooke.com/bbs/thread-18020-1-1.html 总而言之，SQL*PLUS在Linux没有命令上下翻滚功能，甚至也不能使用左右键进行当前命令的修改，这个实在是不爽。。。 上面的文章介绍的工具真的很强大，简单的来说，就是利用rlwrap这个工具来驱动sqlplus来实现上下翻滚以及左右键进行命令修改的功能。 如果你使用的是ubuntu，那么可以直接用apt-get来进行安装，如果你用的是redhat或者centos，那么就要进行编绎了。 rlwrap依赖于libtermcap-devel跟readline-devel，在进行安装之前，你还需要安装这两个包： yum install -y readline-devel libtermcap-devel 然后，你就要下载rlwrap并进行编绎了： wget &#34;http://utopia.knoware.nl/~hlub/rlwrap/rlwrap-0.37.tar.gz&#34;tar -xvf rlwrap-0.37.tar.gzcd rlwrap-0.37./configure &#38;&#38; make &#38;&#38; make check &#38;&#38; make install 之后，你运行: rlwrap sqlplus /nolog 就会发现已经可以进行命令上下翻滚与回退修改了。 当然，为了方便，你也可以把sqlplus alias成 rlwrap，这样子你就不用每次都加rlwrap了]]></description>
			<content:encoded><![CDATA[<p>来源：<a href="http://www.boobooke.com/bbs/thread-18020-1-1.html" target=_blank>http://www.boobooke.com/bbs/thread-18020-1-1.html</a></p>
<p>总而言之，SQL*PLUS在Linux没有命令上下翻滚功能，甚至也不能使用左右键进行当前命令的修改，这个实在是不爽。。。<br />
上面的文章介绍的工具真的很强大，简单的来说，就是利用rlwrap这个工具来驱动sqlplus来实现上下翻滚以及左右键进行命令修改的功能。</p>
<p>如果你使用的是ubuntu，那么可以直接用apt-get来进行安装，如果你用的是redhat或者centos，那么就要进行编绎了。</p>
<p>rlwrap依赖于libtermcap-devel跟readline-devel，在进行安装之前，你还需要安装这两个包：</p>
<div class="hl-surround"><div class="hl-main">yum install -y readline-devel libtermcap-devel</div></div>
<p>然后，你就要下载rlwrap并进行编绎了：</p>
<div class="hl-surround"><div class="hl-main">wget &quot;http://utopia.knoware.nl/~hlub/rlwrap/rlwrap-0.37.tar.gz&quot;<br />tar -xvf rlwrap-0.37.tar.gz<br />cd rlwrap-0.37<br />./configure &amp;&amp; make &amp;&amp; make check &amp;&amp; make install</div></div>
<p>之后，你运行:
<div class="hl-surround"><div class="hl-main">rlwrap sqlplus /nolog</div></div>
<p>就会发现已经可以进行命令上下翻滚与回退修改了。</p>
<p>当然，为了方便，你也可以把sqlplus alias成 rlwrap，这样子你就不用每次都加rlwrap了</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/07/28/how-to-roll-the-commands-from-history-in-sqlpus-under-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>直接在linux中使用sqlplus客户端</title>
		<link>http://blog.myhnet.cn/2010/07/25/using-sqlplus-as-client-in-linux-without-installing-oracle-database/</link>
		<comments>http://blog.myhnet.cn/2010/07/25/using-sqlplus-as-client-in-linux-without-installing-oracle-database/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 02:31:00 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[Error 6]]></category>
		<category><![CDATA[instantclient]]></category>
		<category><![CDATA[oracle客户端]]></category>
		<category><![CDATA[sp1.msb]]></category>
		<category><![CDATA[SP2-0152]]></category>
		<category><![CDATA[SP2-0750]]></category>
		<category><![CDATA[SP2-1503]]></category>
		<category><![CDATA[sqlplus]]></category>
		<category><![CDATA[sqlplus客户端]]></category>
		<category><![CDATA[Unable to initialize Oracle call interface]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=1006</guid>
		<description><![CDATA[首先到oracle的官方网站下载两个包： oracle-instantclient-basic-&#60;release&#62;.i386.ziporacle-instantclient-sqlplus-&#60;release&#62;.i386.zip 这两个其中release部分根据你的服务器端的release所决定，只跟服务器端相同或者比服务器端高，不能低于服务器端版本。 PS：下载地址： http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html 然后，先不要急着解压。我们先建立一个目录，假设为/opt/oracle，然后我们在这里面建立一些子目录 mkdir /opt/oracle/binmkdir /opt/oracle/libmkdir /opt/oracle/tnsmkdir -p /opt/oracle/sqlplus/adminmkdir -p /opt/oracle/sqlplus/mesg 然后，我们解压开始下载的两个包： unzip oracle-instantclient-basic-&#60;release&#62;.i386.zipunzip oracle-instantclient-sqlplus-&#60;release&#62;.i386.zip 解压之后，会得到一个目录，应该是instantclient_release，进入之后，对文件做如下的文件 mv sqlplus /opt/oracle/binmv glogin.sql /opt/oracle/sqlplus/adminmv * /opt/oracle/lib 然后，执行如下命令（最好是写入/etc/profile或者~/.profile） export ORACLE_HOME=/opt/oracleexport PATH=$PATH:$ORACLE_HOME/binexport TNS_ADMIN=$ORACLE_HOME/tnsexport LD_LIBRARY_PATH=$ORACLE_HOME/lib 这个时候，你再执行 sqlplus /nolog 就会发现SQL*PLUS还是不能工作，会报如下这个错误： Error 6 initializing SQL*PlusMessage file sp1&#60;lang&#62;.msb not foundSP2-0750: You may need to set ORACLE_HOME to your Oracle software directory [...]]]></description>
			<content:encoded><![CDATA[<p>首先到oracle的<a href=http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html target=_blank>官方网站</a>下载两个包：</p>
<div class="hl-surround"><div class="hl-main">oracle-instantclient-basic-&lt;release&gt;.i386.zip<br />oracle-instantclient-sqlplus-&lt;release&gt;.i386.zip</div></div>
<p>这两个其中release部分根据你的服务器端的release所决定，只跟服务器端相同或者比服务器端高，<strong>不能</strong>低于服务器端版本。<br />
PS：下载地址：<br />
<a href=http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html target=_blank>http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html</a></p>
<p>然后，先不要急着解压。我们先建立一个目录，假设为/opt/oracle，然后我们在这里面建立一些子目录</p>
<div class="hl-surround"><div class="hl-main">mkdir /opt/oracle/bin<br />mkdir /opt/oracle/lib<br />mkdir /opt/oracle/tns<br />mkdir -p /opt/oracle/sqlplus/admin<br />mkdir -p /opt/oracle/sqlplus/mesg</div></div>
<p>然后，我们解压开始下载的两个包：</p>
<div class="hl-surround"><div class="hl-main">unzip oracle-instantclient-basic-&lt;release&gt;.i386.zip<br />unzip oracle-instantclient-sqlplus-&lt;release&gt;.i386.zip</div></div>
<p>解压之后，会得到一个目录，应该是instantclient_<em>release</em>，进入之后，对文件做如下的文件</p>
<div class="hl-surround"><div class="hl-main">mv sqlplus /opt/oracle/bin<br />mv glogin.sql /opt/oracle/sqlplus/admin<br />mv * /opt/oracle/lib</div></div>
<p>然后，执行如下命令（最好是写入/etc/profile或者~/.profile）</p>
<div class="hl-surround"><div class="hl-main">export ORACLE_HOME=/opt/oracle<br />export PATH=$PATH:$ORACLE_HOME/bin<br />export TNS_ADMIN=$ORACLE_HOME/tns<br />export LD_LIBRARY_PATH=$ORACLE_HOME/lib</div></div>
<p>这个时候，你再执行
<div class="hl-surround"><div class="hl-main">sqlplus /nolog</div></div>
<p>就会发现SQL*PLUS还是不能工作，会报如下这个错误：</p>
<div class="hl-surround"><div class="hl-main">Error 6 initializing SQL*Plus<br />Message file sp1&lt;lang&gt;.msb not found<br />SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory</div></div>
<p>目前这个错误我没有找到真正的原因，但是也有一个临时解决方法：只要从ORACLE服务器端把sp1<lang>.msb与sp2<lang>.msb之类的的文件拷贝过来放在/opt/oracle/sqlplus/mesg中就可以了。如果你不能连接到你的ORACLE服务器去直接拷贝文件，也可以下载我的，用unzip解压，然后移动到/opt/oracle/sqlplus/mesg就可以了。</p>
<p><b><a href='http://blog.myhnet.cn/wp-content/uploads/2010/07/splang.zip'>点击下载msb文件</a></b></p>
<p>之后，你就发现
<div class="hl-surround"><div class="hl-main">$ sqlplus /nolog<br /><br />SQL*Plus: Release 10.2.0.1.0 - Production on Sun Jul 25 10:19:32 2010<br /><br />Copyright (c) 1982, 2005, Oracle.&nbsp; All rights reserved.<br /><br />SQL&gt;</div></div>
<p>也就是说，SQL*PLUS可以工作了。</p>
<p>这个时候，你可以用easy connecting方式或者创建tnsnames.ora文件到/opt/oracle/tns中就可以了连接到你的ORACLE数据库了</p>
<p><strong>PS：</strong><br />
有些朋友可能会碰到如下错误</p>
<div class="hl-surround"><div class="hl-main">SP2-1503: Unable to initialize Oracle call interface<br />SP2-0152: ORACLE may not be functioning properly</div></div>
<p>这个是因为你没有正确安装OCI（oracle call interface），其实就是你没有下载basic那个包，或者LD_LIBRARY_PATH设置错误。你至少要保证你的LD_LIBRARY_PATH里面存在如下四个文件：</p>
<div class="hl-surround"><div class="hl-main">libclntsh.so.10.1&nbsp; libnnz10.so&nbsp; libociei.so&nbsp; libsqlplus.so</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/07/25/using-sqlplus-as-client-in-linux-without-installing-oracle-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux下mysql配置文件my.cnf详解［转］</title>
		<link>http://blog.myhnet.cn/2010/07/22/details-of-my-cnf-for-mysql-in-linux/</link>
		<comments>http://blog.myhnet.cn/2010/07/22/details-of-my-cnf-for-mysql-in-linux/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 23:57:31 +0000</pubDate>
		<dc:creator>myhnet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[配置]]></category>
		<category><![CDATA[配置详解]]></category>
		<category><![CDATA[配置大全]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[my.cnf]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[性能调优]]></category>

		<guid isPermaLink="false">http://blog.myhnet.cn/?p=975</guid>
		<description><![CDATA[mysqld程序：目录和文件 basedir = path 使用给定目录作为根目录(安装目录)。 character-sets-dir = path 给出存放着字符集的目录。 datadir = path 从给定目录读取数据库文件。 pid-file = filename 为mysqld程序指定一个存放进程ID的文件(仅适用于UNIX/Linux系统); Init-V脚本需要使用这个文件里的进程ID结束mysqld进程。 socket = filename 为MySQL客户程序与服务器之间的本地通信指定一个套接字文件(仅适用于UNIX/Linux系统; 默认设置一般是/var/lib/mysql/mysql.sock文件)。在Windows环境下，如果MySQL客户与服务器是通过命名管道进行通信 的，&#8211;sock选项给出的将是该命名管道的名字(默认设置是MySQL)。 lower_case_table_name = 1/0 新目录和数据表的名字是否只允许使用小写字母; 这个选项在Windows环境下的默认设置是1(只允许使用小写字母)。 &#160; mysqld程序：语言设置 character-sets-server = name 新数据库或数据表的默认字符集。为了与MySQL的早期版本保持兼容，这个字符集也可以用&#8211;default-character-set选项给出; 但这个选项已经显得有点过时了。 collation-server = name 新数据库或数据表的默认排序方式。 lanuage = name 用指定的语言显示出错信息。 &#160; mysqld程序：通信、网络、信息安全 enable-named-pipes 允许Windows 2000/XP环境下的客户和服务器使用命名管道(named pipe)进行通信。这个命名管道的默认名字是MySQL，但可以用&#8211;socket选项来改变。 local-infile [=0] 允许/禁止使用LOAD DATA LOCAL语句来处理本地文件。 [...]]]></description>
			<content:encoded><![CDATA[<p><strong>mysqld程序：目录和文件</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>basedir = path</td>
<td>使用给定目录作为根目录(安装目录)。</td>
</tr>
<tr>
<td>character-sets-dir = path</td>
<td>给出存放着字符集的目录。</td>
</tr>
<tr>
<td>datadir = path</td>
<td>从给定目录读取数据库文件。</td>
</tr>
<tr>
<td>pid-file = filename</td>
<td>为mysqld程序指定一个存放进程ID的文件(仅适用于UNIX/Linux系统); Init-V脚本需要使用这个文件里的进程ID结束mysqld进程。</td>
</tr>
<tr>
<td>socket = filename</td>
<td>为MySQL客户程序与服务器之间的本地通信指定一个套接字文件(仅适用于UNIX/Linux系统; 默认设置一般是/var/lib/mysql/mysql.sock文件)。在Windows环境下，如果MySQL客户与服务器是通过命名管道进行通信 的，&#8211;sock选项给出的将是该命名管道的名字(默认设置是MySQL)。</td>
</tr>
<tr>
<td>lower_case_table_name = 1/0</td>
<td>新目录和数据表的名字是否只允许使用小写字母; 这个选项在Windows环境下的默认设置是1(只允许使用小写字母)。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：语言设置</strong></p>
<table border=1 cellspacing=0>
<tr>
<td>character-sets-server = name</td>
<td>新数据库或数据表的默认字符集。为了与MySQL的早期版本保持兼容，这个字符集也可以用&#8211;default-character-set选项给出; 但这个选项已经显得有点过时了。</td>
</tr>
<tr>
<td>collation-server = name</td>
<td>新数据库或数据表的默认排序方式。</td>
</tr>
<tr>
<td>lanuage = name</td>
<td>用指定的语言显示出错信息。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：通信、网络、信息安全</strong></p>
<table border=1 cellspacing=0>
<tr>
<td>enable-named-pipes</td>
<td>允许Windows 2000/XP环境下的客户和服务器使用命名管道(named pipe)进行通信。这个命名管道的默认名字是MySQL，但可以用&#8211;socket选项来改变。</td>
</tr>
<tr>
<td>local-infile [=0]</td>
<td>允许/禁止使用LOAD DATA LOCAL语句来处理本地文件。</td>
</tr>
<tr>
<td>myisam-recover [=opt1, opt2, ...]</td>
<td>在启动时自动修复所有受损的MyISAM数据表。这个选项的可取值有4种:DEFAULT、BACKUP、QUICK和FORCE; 它们与myisamchk程序的同名选项作用相同。</td>
</tr>
<tr>
<td>old-passwords</td>
<td>使用MySQL 3.23和4.0版本中的老算法来加密mysql数据库里的密码(默认使用MySQL 4.1版本开始引入的新加密算法)。</td>
</tr>
<tr>
<td>port = n</td>
<td>为MySQL程序指定一个TCP/IP通信端口(通常是3306端口)。</td>
</tr>
<tr>
<td>safe-user-create</td>
<td>只有在mysql.user数据库表上拥有INSERT权限的用户才能使用GRANT命令; 这是一种双保险机制(此用户还必须具备GRANT权限才能执行GRANT命令)。</td>
</tr>
<tr>
<td>shared-memory</td>
<td>允许使用内存(shared memory)进行通信(仅适用于Windows)。</td>
</tr>
<tr>
<td>shared-memory-base-name = name</td>
<td>给共享内存块起一个名字(默认的名字是MySQL)。</td>
</tr>
<tr>
<td>skip-grant-tables</td>
<td>不使用mysql数据库里的信息来进行访问控制(警告:这将允许用户任何用户去修改任何数据库)。</td>
</tr>
<tr>
<td>skip-host-cache</td>
<td>不使用高速缓存区来存放主机名和IP地址的对应关系。</td>
</tr>
<tr>
<td>skip-name-resovle</td>
<td>不把IP地址解析为主机名; 与访问控制(mysql.user数据表)有关的检查全部通过IP地址行进。</td>
</tr>
<tr>
<td>skip-networking</td>
<td>只允许通过一个套接字文件(Unix/Linux系统)或通过命名管道(Windows系统)进行本地连接，不允许ICP/IP连接; 这提高了安全性，但阻断了来自网络的外部连接和所有的Java客户程序(Java客户即使在本地连接里也使用TCP/IP)。</td>
</tr>
<tr>
<td>user = name</td>
<td>mysqld程序在启动后将在给定UNIX/Linux账户下执行; mysqld必须从root账户启动才能在启动后切换到另一个账户下执行; mysqld_safe脚本将默认使用&#8211;user=mysql选项来启动mysqld程序。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：内存管理、优化、查询缓存区</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>bulk_insert_buffer_size = n</td>
<td>为一次插入多条新记录的INSERT命令分配的缓存区长度(默认设置是8M)。</td>
</tr>
<tr>
<td>key_buffer_size = n</td>
<td>用来存放索引区块的RMA值(默认设置是8M)。</td>
</tr>
<tr>
<td>join_buffer_size = n</td>
<td>在参加JOIN操作的数据列没有索引时为JOIN操作分配的缓存区长度(默认设置是128K)。</td>
</tr>
<tr>
<td>max_heap_table_size = n</td>
<td>HEAP数据表的最大长度(默认设置是16M); 超过这个长度的HEAP数据表将被存入一个临时文件而不是驻留在内存里。</td>
</tr>
<tr>
<td>max_connections = n</td>
<td>MySQL服务器同时处理的数据库连接的最大数量(默认设置是100)。</td>
</tr>
<tr>
<td>query_cache_limit = n</td>
<td>允许临时存放在查询缓存区里的查询结果的最大长度(默认设置是1M)。</td>
</tr>
<tr>
<td>query_cache_size = n</td>
<td>查询缓存区的最大长度(默认设置是0，不开辟查询缓存区)。</td>
</tr>
<tr>
<td>query_cache_type = 0/1/2</td>
<td>查询缓存区的工作模式:0, 禁用查询缓存区; 1，启用查询缓存区(默认设置); 2，&#8221;按需分配&#8221;模式，只响应SELECT SQL_CACHE命令。</td>
</tr>
<tr>
<td>read_buffer_size = n</td>
<td>为从数据表顺序读取数据的读操作保留的缓存区的长度(默认设置是128KB); 这个选项的设置值在必要时可以用SQL命令SET SESSION read_buffer_size = n命令加以改变。</td>
</tr>
<tr>
<td>read_rnd_buffer_size = n</td>
<td>类似于read_buffer_size选项，但针对的是按某种特定顺序(比如使用了ORDER BY子句的查询)输出的查询结果(默认设置是256K)。</td>
</tr>
<tr>
<td>sore_buffer = n</td>
<td>为排序操作分配的缓存区的长度(默认设置是2M); 如果这个缓存区太小，则必须创建一个临时文件来进行排序。</td>
</tr>
<tr>
<td>table_cache = n</td>
<td>同时打开的数据表的数量(默认设置是64)。</td>
</tr>
<tr>
<td>tmp_table_size = n</td>
<td>临时HEAP数据表的最大长度(默认设置是32M); 超过这个长度的临时数据表将被转换为MyISAM数据表并存入一个临时文件。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：日志</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>log [= file]</td>
<td>把所有的连接以及所有的SQL命令记入日志(通用查询日志); 如果没有给出file参数，MySQL将在数据库目录里创建一个hostname.log文件作为这种日志文件(hostname是服务器的主机名)。</td>
</tr>
<tr>
<td>log-slow-queries [= file]</td>
<td>把执行用时超过long_query_time变量值的查询命令记入日志(慢查询日志); 如果没有给出file参数，MySQL将在数据库目录里创建一个hostname-slow.log文件作为这种日志文件(hostname是服务器主机 名)。</td>
</tr>
<tr>
<td>long_query_time = n</td>
<td>慢查询的执行用时上限(默认设置是10s)。</td>
</tr>
<tr>
<td>long_queries_not_using_indexs</td>
<td>把慢查询以及执行时没有使用索引的查询命令全都记入日志(其余同&#8211;log-slow-queries选项)。</td>
</tr>
<tr>
<td>log-bin [= filename]</td>
<td>把对数据进行修改的所有SQL命令(也就是INSERT、UPDATE和DELETE命令)以二进制格式记入日志(二进制变更日志，binary update log)。这种日志的文件名是filename.n或默认的hostname.n，其中n是一个6位数字的整数(日志文件按顺序编号)。</td>
</tr>
<tr>
<td>log-bin-index = filename</td>
<td>二进制日志功能的索引文件名。在默认情况下，这个索引文件与二进制日志文件的名字相同，但后缀名是.index而不是.nnnnnn。</td>
</tr>
<tr>
<td>max_binlog_size = n</td>
<td>二进制日志文件的最大长度(默认设置是1GB)。在前一个二进制日志文件里的信息量超过这个最大长度之前，MySQL服务器会自动提供一个新的二进制日志文件接续上。</td>
</tr>
<tr>
<td>binlog-do-db = dbname</td>
<td>只把给定数   据库里的变化情况记入二进制日志文件，其他数据库里的变化情况不记载。如果需要记载多个数据库里的变化情况，就必须在配置文件使用多个本选项来设置，每个数据库一行。</td>
</tr>
<tr>
<td>binlog-ignore-db = dbname</td>
<td>不把给定数据库里的变化情况记入二进制日志文件。</td>
</tr>
<tr>
<td>sync_binlog = n</td>
<td>每经过n次日志写操作就把日志文件写入硬盘一次(对日志信息进行一次同步)。n=1是最安全的做法，但效率最低。默认设置是n=0，意思是由操作系统来负责二进制日志文件的同步工作。</td>
</tr>
<tr>
<td>log-update [= file]</td>
<td>记载出错情况的日志文件名(出错日志)。这种日志功能无法禁用。如果没有给出file参数，MySQL会使用hostname.err作为种日志文件的名字。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：镜像(主控镜像服务器)</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>server-id = n</td>
<td>给服务器分配一个独一无二的ID编号; n的取值范围是1~2的32次方启用二进制日志功能。</td>
</tr>
<tr>
<td>log-bin = name</td>
<td>启用二进制日志功能。这种日志的文件名是filename.n或默认的hostname.n，其中的n是一个6位数字的整数(日志文件顺序编号)。</td>
</tr>
<tr>
<td>binlog-do/ignore-db = dbname</td>
<td>只把给定数据库里的变化情况记入二进制日志文件/不把给定的数据库里的变化记入二进制日志文件。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：镜像(从属镜像服务器)</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>server-id = n</td>
<td>给服务器分配一个唯一的ID编号</td>
</tr>
<tr>
<td>log-slave-updates</td>
<td>启用从属服务器上的日志功能，使这台计算机可以用来构成一个镜像链(A->B->C)。</td>
</tr>
<tr>
<td>master-host = hostname</td>
<td>主控服务器的主机名或IP地址。如果从属服务器上存在mater.info文件(镜像关系定义文件)，它将忽略此选项。</td>
</tr>
<tr>
<td>master-user = replicusername</td>
<td>从属服务器用来连接主控服务器的用户名。如果从属服务器上存在mater.info文件，它将忽略此选项。</td>
</tr>
<tr>
<td>master-password = passwd</td>
<td>从属服务器用来连接主控服务器的密码。如果从属服务器上存在mater.info文件，它将忽略此选项。</td>
</tr>
<tr>
<td>master-port = n</td>
<td>从属服务器用来连接主控服务器的TCP/IP端口(默认设置是3306端口)。</td>
</tr>
<tr>
<td>master-connect-retry = n</td>
<td>如果与主控服务器的连接没有成功，则等待n秒(s)后再进行管理方式(默认设置是60s)。如果从属服务器存在mater.info文件，它将忽略此选项。</td>
</tr>
<tr>
<td>master-ssl-xxx = xxx</td>
<td>对主、从服务器之间的SSL通信进行配置。</td>
</tr>
<tr>
<td>read-only = 0/1</td>
<td>0: 允许从属服务器独立地执行SQL命令(默认设置); 1: 从属服务器只能执行来自主控服务器的SQL命令。</td>
</tr>
<tr>
<td>read-log-purge = 0/1</td>
<td>1: 把处理完的SQL命令立刻从中继日志文件里删除(默认设置); 0: 不把处理完的SQL命令立刻从中继日志文件里删除。</td>
</tr>
<tr>
<td>replicate-do-table = dbname.tablename </td>
<td>与&#8211;replicate-do-table选项的含义和用法相同，但数据库和数据库表名字里允许出现通配符&#8221;%&#8221; (例如: test%.%&#8211;对名字以&#8221;test&#8221;开头的所有数据库里的所以数据库表进行镜像处理)。</p>
<tr>
<td>replicate-do-db = name</td>
<td>只对这个数据库进行镜像处理。</td>
</tr>
<tr>
<td>replicate-ignore-table = dbname.tablename</td>
<td> 不对这个数据表进行镜像处理。</td>
</tr>
<tr>
<td>replicate-wild-ignore-table = dbn.tablen</td>
<td>不对这些数据表进行镜像处理。</td>
</tr>
<tr>
<td>replicate-ignore-db = dbname</td>
<td>不对这个数据库进行镜像处理。</td>
</tr>
<tr>
<td>replicate-rewrite-db = db1name > db2name</td>
<td>把主控数据库上的db1name数据库镜像处理为从属服务器上的db2name数据库。</td>
</tr>
<tr>
<td>report-host = hostname</td>
<td>从属服务器的主机名; 这项信息只与SHOW SLAVE HOSTS命令有关&#8211;主控服务器可以用这条命令生成一份从属服务器的名单。</td>
</tr>
<tr>
<td>slave-compressed-protocol = 1</td>
<td>主、从服务器使用压缩格式进行通信&#8211;如果它们都支持这么做的话。</td>
</tr>
<tr>
<td>slave-skip-errors = n1, n2, &#8230;或all</td>
<td>即使发生出错代码为n1、n2等的错误，镜像处理工作也继续进行(即不管发生什么错误，镜像处理工作也继续进行)。如果配置得当，从属服务器不应该在执行 SQL命令时发生错误(在主控服务器上执行出错的SQL命令不会被发送到从属服务器上做镜像处理); 如果不使用slave-skip-errors选项，从属服务器上的镜像工作就可能因为发生错误而中断，中断后需要有人工参与才能继续进行。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld&#8211;InnoDB：基本设置、表空间文件</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>skip-innodb</td>
<td>不加载InnoDB数据表驱动程序&#8211;如果用不着InnoDB数据表，可以用这个选项节省一些内存。</td>
</tr>
<tr>
<td>innodb-file-per-table</td>
<td>为每一个新数据表创建一个表空间文件而不是把数据表都集中保存在中央表空间里(后者是默认设置)。该选项始见于MySQL 4.1。</td>
</tr>
<tr>
<td>innodb-open-file = n</td>
<td>InnoDB数据表驱动程序最多可以同时打开的文件数(默认设置是300)。如果使用了innodb-file-per-table选项并且需要同时打开很多数据表的话，这个数字很可能需要加大。</td>
</tr>
<tr>
<td>innodb_data_home_dir = p</td>
<td>InnoDB主目录，所有与InnoDB数据表有关的目录或文件路径都相对于这个路径。在默认的情况下，这个主目录就是MySQL的数据目录。</td>
</tr>
<tr>
<td>innodb_data_file_path = ts </td>
<td>用来容纳InnoDB为数据表的表空间: 可能涉及一个以上的文件; 每一个表空间文件的最大长度都必须以字节(B)、兆字节(MB)或千兆字节(GB)为单位给出; 表空间文件的名字必须以分号隔开; 最后一个表空间文件还可以带一个autoextend属性和一个最大长度(max:n)。例如，ibdata1:1G; ibdata2:1G:autoextend:max:2G的意思是: 表空间文件ibdata1的最大长度是1GB，ibdata2的最大长度也是1G，但允许它扩充到2GB。除文件名外，还可以用硬盘分区的设置名来定义表 空间，此时必须给表空间的最大初始长度值加上newraw关键字做后缀，给表空间的最大扩充长度值加上raw关键字做后缀(例如/dev/hdb1: 20Gnewraw或/dev/hdb1:20Graw); MySQL 4.0及更高版本的默认设置是ibdata1:10M:autoextend。</td>
</tr>
<tr>
<td>innodb_autoextend_increment = n</td>
<td>带有autoextend属性的表空间文件每次加大多少兆字节(默认设置是8MB)。这个属性不涉及具体的数据表文件，那些文件的增大速度相对是比较小的。</td>
</tr>
<tr>
<td>innodb_lock_wait_timeout = n</td>
<td>如果某个事务在等待n秒(s)后还没有获得所需要的资源，就使用ROLLBACK命令放弃这个事务。这项设置对于发现和处理未能被InnoDB数据表驱动 程序识别出来的死锁条件有着重要的意义。这个选项的默认设置是50s。</td>
</tr>
<tr>
<td>innodb_fast_shutdown 0/1</td>
<td>是否以最快的速度关闭InnoDB，默认设置是1，意思是不把缓存在INSERT缓存区的数据写入数据表，那些数据将在MySQL服务器下次启动时再写入 (这么做没有什么风险，因为INSERT缓存区是表空间的一个组成部分，数据不会丢失)。把这个选项设置为0反面危险，因为在计算机关闭时，InnoDB 驱动程序很可能没有足够的时间完成它的数据同步工作，操作系统也许会在它完成数据同步工作之前强行结束InnoDB，而这会导致数据不完整。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：InnoDB&#8211;日志</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>innodb_log_group_home_dir = p</td>
<td>用来存放InnoDB日志文件的目录路径(如ib_logfile0、ib_logfile1等)。在默认的情况下，InnoDB驱动程序将使用 MySQL数据目录作为自己保存日志文件的位置。</td>
</tr>
<tr>
<td>innodb_log_files_in_group = n</td>
<td>使用多少个日志文件(默认设置是2)。InnoDB数据表驱动程序将以轮转方式依次填写这些文件; 当所有的日志文件都写满以后，之后的日志信息将写入第一个日志文件的最大长度(默认设置是5MB)。这个长度必须以MB(兆字节)或GB(千兆字节)为单 位进行设置。</td>
</tr>
<tr>
<td>innodb_flush_log_at_trx_commit = 0/1/2</td>
<td>这个选项决定着什么时候把日志信息写入日志文件以及什么时候把这些文件物理地写(术语称为&#8221;同步&#8221;)到硬盘上。设置值0的意思是每隔一秒写一次日志并进行 同步，这可以减少硬盘写操作次数，但可能造成数据丢失; 设置值1(设置设置)的意思是在每执行完一条COMMIT命令就写一次日志并进行同步，这可以防止数据丢失，但硬盘写操作可能会很频繁; 设置值2是一般折衷的办法，即每执行完一条COMMIT命令写一次日志，每隔一秒进行一次同步。</td>
</tr>
<tr>
<td>innodb_flush_method = x</td>
<td>InnoDB日志文件的同步办法(仅适用于UNIX/Linux系统)。这个选项的可取值有两种: fdatasync，用fsync()函数进行同步; O_DSYNC，用O_SYNC()函数进行同步。</td>
</tr>
<tr>
<td>innodb_log_archive = 1</td>
<td>启用InnoDB驱动程序的archive(档案)日志功能，把日志信息写入ib_arch_log_n文件。启用这种日志功能在InnoDB与 MySQL一起使用时没有多大意义(启用MySQL服务器的二进制日志功能就足够用了)。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序&#8211;InnoDB：缓存区的设置和优化</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>innodb_log_buffer_pool_size = n</td>
<td>为InnoDB数据表及其索引而保留的RAM内存量(默认设置是8MB)。这个参数对速度有着相当大的影响，如果计算机上只运行有 MySQL/InnoDB数据库服务器，就应该把全部内存的80%用于这个用途。</p>
<tr>
<td>innodb_log_buffer_size = n</td>
<td>事务日志文件写操作缓存区的最大长度(默认设置是1MB)。</td>
</tr>
<tr>
<td>innodb_additional_men_pool_size = n</td>
<td>为用于内部管理的各种数据结构分配的缓存区最大长度(默认设置是1MB)。</td>
</tr>
<tr>
<td>innodb_file_io_threads = n</td>
<td>I/O操作(硬盘写操作)的最大线程个数(默认设置是4)。</td>
</tr>
<tr>
<td>innodb_thread_concurrency = n</td>
<td>InnoDB驱动程序能够同时使用的最大线程个数(默认设置是8)。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><strong>mysqld程序：其它选项</strong></p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<td>bind-address = ipaddr</td>
<td>MySQL服务器的IP地址。如果MySQL服务器所在的计算机有多个IP地址，这个选项将非常重要。</td>
</tr>
<tr>
<td>default-storage-engine = type</td>
<td>新数据表的默认数据表类型(默认设置是MyISAM)。这项设置还可以通过&#8211;default-table-type选项来设置。</td>
</tr>
<tr>
<td>default-timezone = name</td>
<td>为MySQL服务器设置一个地理时区(如果它与本地计算机的地理时区不一样)。</td>
</tr>
<tr>
<td>ft_min_word_len = n</td>
<td>全文索引的最小单词长度工。这个选项的默认设置是4，意思是在创建全文索引时不考虑那些由3个或更少的字符构建单词。</td>
</tr>
<tr>
<td>Max-allowed-packet = n</td>
<td>客户与服务器之间交换的数据包的最大长度，这个数字至少应该大于客户程序将要处理的最大BLOB块的长度。这个选项的默认设置是1MB。</td>
</tr>
<tr>
<td>Sql-mode = model1, mode2, &#8230; </td>
<td>MySQL将运行在哪一种SQL模式下。这个选项的作用是让MySQL与其他的数据库系统保持最大程度的兼容。这个选项的可取值包括ansi、db2、 oracle、no_zero_date、pipes_as_concat。</td>
</tr>
</table>
<p>&nbsp;</p>
<p><font color=red>注意：如果在配置文件里给出的某个选项是mysqld无法识别的，MySQL服务器将不启动。</font></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.myhnet.cn/2010/07/22/details-of-my-cnf-for-mysql-in-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
