<?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>Linux&#124;系统管理&#124;WEB开发 &#187; bash</title>
	<atom:link href="http://blog.wgzhao.com/tag/bash/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.wgzhao.com</link>
	<description>关注Linux，系统管理，WEB开发以及开源世界</description>
	<lastBuildDate>Wed, 14 Jul 2010 08:00:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>bash的可选项</title>
		<link>http://blog.wgzhao.com/2009/08/26/options-of-bash.html</link>
		<comments>http://blog.wgzhao.com/2009/08/26/options-of-bash.html#comments</comments>
		<pubDate>Wed, 26 Aug 2009 10:12:09 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[abs]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[option]]></category>

		<guid isPermaLink="false">http://mlsx.xplore.cn/?p=1845</guid>
		<description><![CDATA[可选项（options）设置用来改变shell或者脚本的行为。
set指令可以使得在一个脚本里设置可选项。在脚本你需要设置可选项的地方，实用set -o option-name，或者采取缩写模式的set -option-abbrev。这两种形式效果等价。
比如

#!/bin/bash
set -o verbose
#Echoes all commands before executing
#---------------------------
set -v
#Exact same effect as above


如果想进制某一个可选项，使用+，而不是-符号：set +o option-name / set +option-abbrev 

#!/bin/bash
set -o verbose
# Command echoing on.
command
...
command
set +o verbose
# Command echoing off.
command
# Not echoed.
set -v
# Command echoing on.
command
...
command
set +v
# Command echoing off.
command
exit 0

还有一种方法就是在指定shell解释器的同时设置可选项，就像下面这样：

#!/bin/bash -x
#
# Body of script follows.

当然，你可以在执行脚本的同时设定可选项，比如：

$ bash -v script-name
$ bash -o verbose script-name

上面两条指令效果相同。
有关bash的可选参数及解释见下表



缩写
名字
效果




-B
brace expansion
可以括号展开(缺省为on)


+B
brace [...]]]></description>
			<content:encoded><![CDATA[<p>可选项（options）设置用来改变shell或者脚本的行为。<br />
set指令可以使得在一个脚本里设置可选项。在脚本你需要设置可选项的地方，实用<strong>set -o option-name</strong>，或者采取缩写模式的<strong>set -option-abbrev</strong>。这两种形式效果等价。<br />
比如</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-o</span> verbose
<span style="color: #666666; font-style: italic;">#Echoes all commands before executing</span>
<span style="color: #666666; font-style: italic;">#---------------------------</span>
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-v</span>
<span style="color: #666666; font-style: italic;">#Exact same effect as above</span></pre></div></div>

<p><span id="more-1845"></span><br />
如果想进制某一个可选项，使用+，而不是-符号：<strong>set +o option-name / set +option-abbrev </strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-o</span> verbose
<span style="color: #666666; font-style: italic;"># Command echoing on.</span>
<span style="color: #7a0874; font-weight: bold;">command</span>
...
<span style="color: #7a0874; font-weight: bold;">command</span>
<span style="color: #000000; font-weight: bold;">set</span> +o verbose
<span style="color: #666666; font-style: italic;"># Command echoing off.</span>
<span style="color: #7a0874; font-weight: bold;">command</span>
<span style="color: #666666; font-style: italic;"># Not echoed.</span>
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-v</span>
<span style="color: #666666; font-style: italic;"># Command echoing on.</span>
<span style="color: #7a0874; font-weight: bold;">command</span>
...
<span style="color: #7a0874; font-weight: bold;">command</span>
<span style="color: #000000; font-weight: bold;">set</span> +v
<span style="color: #666666; font-style: italic;"># Command echoing off.</span>
<span style="color: #7a0874; font-weight: bold;">command</span>
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p>还有一种方法就是在指定shell解释器的同时设置可选项，就像下面这样：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash -x</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Body of script follows.</span></pre></div></div>

<p>当然，你可以在执行脚本的同时设定可选项，比如：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-v</span> script-name
$ <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-o</span> verbose script-name</pre></div></div>

<p>上面两条指令效果相同。</p>
<p>有关bash的可选参数及解释见下表</p>
<table border="1">
<thead>
<tr>
<th>缩写</th>
<th>名字</th>
<th>效果</th>
</tr>
</thead>
<tbody>
<tr>
<td>-B</td>
<td>brace expansion</td>
<td>可以括号展开(缺省为on)</td>
</tr>
<tr>
<td>+B</td>
<td>brace expansion</td>
<td>不可以括号展开</td>
</tr>
<tr>
<td>-C</td>
<td>noclobber</td>
<td>防止通过重定向覆盖文件(&gt;1可以覆盖此规则)</td>
</tr>
<tr>
<td>-D</td>
<td>(none)</td>
<td>列出$开头的双引号引起来的字符串，但是不执行脚本里的命令</td>
</tr>
<tr>
<td>-a</td>
<td>allexport</td>
<td>导出所有已定义的变量</td>
</tr>
<tr>
<td>-b</td>
<td>notify</td>
<td>后台任务终止时给出提示（不大用在脚本里）</td>
</tr>
<tr>
<td>-c &#8230;</td>
<td>(none)</td>
<td>从&#8230;读取命令</td>
</tr>
<tr>
<td>-e</td>
<td>errexit</td>
<td>当一个命令是非0状态退出时，脚本在第一个错误处中止(abort)（除until/while循环，if-tests,列表结构（命令链）</td>
</tr>
<tr>
<td>-f</td>
<td>noglob</td>
<td>文件名展开（通配符）禁止</td>
</tr>
<tr>
<td>-i</td>
<td>interactive</td>
<td>交互模式运行脚本</td>
</tr>
<tr>
<td>-n</td>
<td>noexec</td>
<td>读脚本的指令，但是不执行（做语法检测）</td>
</tr>
<tr>
<td>-o option-name</td>
<td>(none)</td>
<td>调用<em>option-name</em>参数</td>
</tr>
<tr>
<td>-o posix</td>
<td>POSIX</td>
<td>改变bash或者调用的脚本行为，使其符合POSIX标准</td>
</tr>
<tr>
<td>-o pipefail</td>
<td>pipe failure</td>
<td>管道里出现非零返回值时，使用用管道返回管道最后一个命令的推出状态</td>
</tr>
<tr>
<td>-p</td>
<td>privileged</td>
<td>脚本带suid位执行（注意！）</td>
</tr>
<tr>
<td>-r</td>
<td>restricted</td>
<td>脚本运行在限制模式</td>
</tr>
<tr>
<td>-s</td>
<td>stdin</td>
<td>从stdin读命令</td>
</tr>
<tr>
<td>-t</td>
<td>(none)</td>
<td>第一个命令后退出</td>
</tr>
<tr>
<td>-u</td>
<td>nounset</td>
<td>使用未定义的变量时，输出错误消息，并强制退出</td>
</tr>
<tr>
<td>-v</td>
<td>verbose</td>
<td>执行指令前，将其打印到标准输出</td>
</tr>
<tr>
<td>-x</td>
<td>xtrace</td>
<td>和-v类似，但是展开命令</td>
</tr>
<tr>
<td>-</td>
<td>(none)</td>
<td>可选参数结束符。所有其他参数当做位置参数</td>
</tr>
<tr>
<td>&#8211;</td>
<td>(none)</td>
<td>取消位置参数设置，如果给出的参数( &#8212; arg1 arg2)，位置参数设置为参数</td>
</tr>
</tbody>
</table>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2009/08/26/options-of-bash.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2009/08/26/options-of-bash.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bash里的here document</title>
		<link>http://blog.wgzhao.com/2009/08/24/here-documents-in-bash.html</link>
		<comments>http://blog.wgzhao.com/2009/08/24/here-documents-in-bash.html#comments</comments>
		<pubDate>Mon, 24 Aug 2009 03:16:10 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[abs]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[here-document]]></category>

		<guid isPermaLink="false">http://mlsx.xplore.cn/?p=1842</guid>
		<description><![CDATA[不得不再一次说，Advanced bash-scripting guide(a.k.a ABS)这本书太强悍了，对于bash里的Here  Document用法，我说见过的其他关于shell/bash编程的书里，都是简单的介绍这个东西是做什么的，基本用法是什么，然后给出一个例子就完成了。我也一直以为他就是为了便于多行的输入。但是看完ABS对此一整章的介绍，我才发现，其实here document没有那么简单。这里就不全文翻译了，把几种用法总结一下吧。


简单用法
可以用在简单的命令输出，交互程序里。给出几个例子：

#!/bin/bash
&#160;
wall &#60; &#60;zzz23EndOfMessagezzz23
E-mail your noontime orders for pizza to the system administrator.
    &#40;Add an extra dollar for anchovy or mushroom topping.&#41;
# Additional message text goes here.
# Note: 'wall' prints comment lines.
zzz23EndOfMessagezzz23
&#160;
# Could have been done more efficiently by
#         [...]]]></description>
			<content:encoded><![CDATA[<p>不得不再一次说，<a href="http://tldp.org/LDP/abs/html">Advanced bash-scripting guide(a.k.a ABS)</a>这本书太强悍了，对于bash里的Here  Document用法，我说见过的其他关于shell/bash编程的书里，都是简单的介绍这个东西是做什么的，基本用法是什么，然后给出一个例子就完成了。我也一直以为他就是为了便于多行的输入。但是看完ABS对此<a href="http://tldp.org/LDP/abs/html/here-docs.html">一整章的介绍</a>，我才发现，其实here document没有那么简单。这里就不全文翻译了，把几种用法总结一下吧。<br />
<span id="more-1842"></span></p>
<ul>
<li><tt>简单用法</tt><br />
可以用在简单的命令输出，交互程序里。给出几个例子：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">wall</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>zzz23EndOfMessagezzz23
E-mail your noontime orders <span style="color: #000000; font-weight: bold;">for</span> pizza to the system administrator.
    <span style="color: #7a0874; font-weight: bold;">&#40;</span>Add an extra dollar <span style="color: #000000; font-weight: bold;">for</span> anchovy or mushroom topping.<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #666666; font-style: italic;"># Additional message text goes here.</span>
<span style="color: #666666; font-style: italic;"># Note: 'wall' prints comment lines.</span>
zzz23EndOfMessagezzz23
&nbsp;
<span style="color: #666666; font-style: italic;"># Could have been done more efficiently by</span>
<span style="color: #666666; font-style: italic;">#         wall &lt;message-file</span>
<span style="color: #666666; font-style: italic;">#  However, embedding the message template in a script</span>
<span style="color: #666666; font-style: italic;">#+ is a quick-and-dirty one-off solution.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

<p>&#8212;&#8212;&#8211;
</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">!/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Noninteractive use of 'vi' to edit a file.</span>
<span style="color: #666666; font-style: italic;"># Emulates 'sed'.</span>
&nbsp;
<span style="color: #007800;">E_BADARGS</span>=<span style="color: #000000;">85</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: <span style="color: #780078;">`basename $0`</span> filename&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$E_BADARGS</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #007800;">TARGETFILE</span>=$<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Insert 2 lines in file, then save.</span>
<span style="color: #666666; font-style: italic;">#--------Begin here document-----------#</span>
<span style="color: #c20cb9; font-weight: bold;">vi</span> <span style="color: #007800;">$TARGETFILE</span> <span style="color: #000000; font-weight: bold;">&amp;</span>lt;.
&nbsp;
<span style="color: #666666; font-style: italic;">#  Bram Moolenaar points out that this may not work with 'vim'</span>
<span style="color: #666666; font-style: italic;">#+ because of possible problems with terminal interaction.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

</li>
<li><tt>进制前导tab输出</tt><br />
这是从曾经遇到的一个问题，在Heredocument里，我为了代码格式好看，采取了tab缩进的方式，但是带来的坏处就是这些tab键也会成为输出，而这并不是我所需要的。因此我需要一个即解决代码格式美观，又不影响输出的办法，原来here document能做到这点，那就是在给出的limit string之前加上一个-符号，比如：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>- HERE
          include leading tab
      include leading space
HERE
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
<span style="color: #660033;">------------------------------</span>
$ .<span style="color: #000000; font-weight: bold;">/</span>test.sh
includeing a leading tab
   includeing some spaces</pre></div></div>

<p>注：他仅仅只是制止前导tab键，对于空格则不受影响。另外要注意的是，如果你的编辑器设置了tab转空格的话，那你会发现以上代码似乎并不是生效。因为所有的tab都转成4个或者8个或者你设置的数量个空格符号了。</pre>
</li>
<li><tt>参数替代</tt><br />
here document支持参数和命令替代，可以传递不同的参数给here document文本，从而获得不同的输出，比如：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># Another 'cat' here document, using parameter substitution.</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Try it with no command-line parameters,   ./scriptname</span>
<span style="color: #666666; font-style: italic;"># Try it with one command-line parameter,   ./scriptname Mortimer</span>
<span style="color: #666666; font-style: italic;"># Try it with one two-word quoted command-line parameter,</span>
<span style="color: #666666; font-style: italic;">#                           ./scriptname &quot;Mortimer Jones&quot;</span>
&nbsp;
<span style="color: #007800;">CMDLINEPARAM</span>=<span style="color: #000000;">1</span>     <span style="color: #666666; font-style: italic;">#  Expect at least command-line parameter.</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-ge</span> <span style="color: #007800;">$CMDLINEPARAM</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #007800;">NAME</span>=$<span style="color: #000000;">1</span>          <span style="color: #666666; font-style: italic;">#  If more than one command-line param,</span>
                   <span style="color: #666666; font-style: italic;">#+ then just take the first.</span>
<span style="color: #000000; font-weight: bold;">else</span>
  <span style="color: #007800;">NAME</span>=<span style="color: #ff0000;">&quot;John Doe&quot;</span>  <span style="color: #666666; font-style: italic;">#  Default, if no command-line parameter.</span>
<span style="color: #000000; font-weight: bold;">fi</span>  
&nbsp;
<span style="color: #007800;">RESPONDENT</span>=<span style="color: #ff0000;">&quot;the author of this fine script&quot;</span>  
&nbsp;
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>Endofmessage
&nbsp;
Hello, there, <span style="color: #007800;">$NAME</span>.
Greetings to you, <span style="color: #007800;">$NAME</span>, from <span style="color: #007800;">$RESPONDENT</span>.
&nbsp;
<span style="color: #666666; font-style: italic;"># This comment shows up in the output (why?).</span>
&nbsp;
Endofmessage
&nbsp;
<span style="color: #666666; font-style: italic;"># Note that the blank lines show up in the output.</span>
<span style="color: #666666; font-style: italic;"># So does the comment.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

</pre>
</li>
<li><tt>关闭参数替代</tt><br />
给limit string加上转移或者引号，就可以进制here document的文本参数或者命令替代，这对于生成脚本甚至程序代码提供了帮助。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;">#  A 'cat' here-document, but with parameter substitution disabled.</span>
&nbsp;
<span style="color: #007800;">NAME</span>=<span style="color: #ff0000;">&quot;John Doe&quot;</span>
<span style="color: #007800;">RESPONDENT</span>=<span style="color: #ff0000;">&quot;the author of this fine script&quot;</span>  
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #ff0000;">'Endofmessage'</span>
&nbsp;
Hello, there, <span style="color: #007800;">$NAME</span>.
Greetings to you, <span style="color: #007800;">$NAME</span>, from <span style="color: #007800;">$RESPONDENT</span>.
&nbsp;
Endofmessage
&nbsp;
<span style="color: #666666; font-style: italic;">#   No parameter substitution when the &quot;limit string&quot; is quoted or escaped.</span>
<span style="color: #666666; font-style: italic;">#   Either of the following at the head of the here document would have</span>
<span style="color: #666666; font-style: italic;">#+  the same effect.</span>
<span style="color: #666666; font-style: italic;">#   cat &lt;&lt;&quot;Endofmessage&quot;</span>
<span style="color: #666666; font-style: italic;">#   cat &lt;&lt;\Endofmessage</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

<p>-----
</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># generate-script.sh</span>
<span style="color: #666666; font-style: italic;"># Based on an idea by Albert Reiner.</span>
&nbsp;
<span style="color: #007800;">OUTFILE</span>=generated.sh         <span style="color: #666666; font-style: italic;"># Name of the file to generate.</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># -----------------------------------------------------------</span>
<span style="color: #666666; font-style: italic;"># 'Here document containing the body of the generated script.</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #ff0000;">'EOF'</span>
<span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;This is a generated shell script.&quot;</span>
<span style="color: #666666; font-style: italic;">#  Note that since we are inside a subshell,</span>
<span style="color: #666666; font-style: italic;">#+ we can't access variables in the &quot;outside&quot; script.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Generated file will be named: <span style="color: #007800;">$OUTFILE</span>&quot;</span>
<span style="color: #666666; font-style: italic;">#  Above line will not work as normally expected</span>
<span style="color: #666666; font-style: italic;">#+ because parameter expansion has been disabled.</span>
<span style="color: #666666; font-style: italic;">#  Instead, the result is literal output.</span>
&nbsp;
<span style="color: #007800;">a</span>=<span style="color: #000000;">7</span>
<span style="color: #007800;">b</span>=<span style="color: #000000;">3</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">let</span> <span style="color: #ff0000;">&quot;c = <span style="color: #007800;">$a</span> * <span style="color: #007800;">$b</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;c = <span style="color: #007800;">$c</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
EOF
<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$OUTFILE</span>
<span style="color: #666666; font-style: italic;"># -----------------------------------------------------------</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#  Quoting the 'limit string' prevents variable expansion</span>
<span style="color: #666666; font-style: italic;">#+ within the body of the above 'here document.'</span>
<span style="color: #666666; font-style: italic;">#  This permits outputting literal strings in the output file.</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$OUTFILE</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">755</span> <span style="color: #007800;">$OUTFILE</span>
  <span style="color: #666666; font-style: italic;"># Make the generated file executable.</span>
<span style="color: #000000; font-weight: bold;">else</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Problem in creating file: <span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #007800;">$OUTFILE</span><span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#  This method can also be used for generating</span>
<span style="color: #666666; font-style: italic;">#+ C programs, Perl programs, Python programs, Makefiles,</span>
<span style="color: #666666; font-style: italic;">#+ and the like.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p>我们也可以利用here document的输出来设置变量，这其实算是命令替代的一种迂回方式了。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">variable</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>SETVAR
This variable
runs over multiple lines.
SETVAR<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$variable</span>&quot;</span></pre></div></div>

</pre>
</li>
<li><tt>充当函数输入功能</tt><br />
here document也能提供在同一个脚本里一个函数的输入能力。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># here-function.sh</span>
&nbsp;
GetPersonalData <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #c20cb9; font-weight: bold;">read</span> firstname
  <span style="color: #c20cb9; font-weight: bold;">read</span> lastname
  <span style="color: #c20cb9; font-weight: bold;">read</span> address
  <span style="color: #c20cb9; font-weight: bold;">read</span> city 
  <span style="color: #c20cb9; font-weight: bold;">read</span> state 
  <span style="color: #c20cb9; font-weight: bold;">read</span> zipcode
<span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #666666; font-style: italic;"># This certainly looks like an interactive function, but...</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># Supply input to the above function.</span>
GetPersonalData <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>RECORD001
Bozo
Bozeman
<span style="color: #000000;">2726</span> Nondescript Dr.
Baltimore
MD
<span style="color: #000000;">21226</span>
RECORD001
&nbsp;
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$firstname</span> <span style="color: #007800;">$lastname</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$address</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$city</span>, <span style="color: #007800;">$state</span> <span style="color: #007800;">$zipcode</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p>或者可以像下面这种匿名功能一样：
</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
: <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>TESTVARIABLES
<span style="color: #800000;">${HOSTNAME?}</span><span style="color: #800000;">${USER?}</span><span style="color: #800000;">${MAIL?}</span>  <span style="color: #666666; font-style: italic;"># Print error message if one of the variables not set.</span>
TESTVARIABLES
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$?</span></pre></div></div>

</pre>
</li>
<li><tt>注释代码块</tt><br />
用来快速注释注释一段代码，一般用于调试目的，看下面这个比较长的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># commentblock.sh</span>
&nbsp;
: <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>COMMENTBLOCK
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;This line will not echo.&quot;</span>
This is a comment line missing the <span style="color: #ff0000;">&quot;#&quot;</span> prefix.
This is another comment line missing the <span style="color: #ff0000;">&quot;#&quot;</span> prefix.
&nbsp;
<span style="color: #000000; font-weight: bold;">&amp;*@!!</span>++=
The above line will cause no error message,
because the Bash interpreter will ignore it.
COMMENTBLOCK
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Exit value of above <span style="color: #000099; font-weight: bold;">\&quot;</span>COMMENTBLOCK<span style="color: #000099; font-weight: bold;">\&quot;</span> is $?.&quot;</span>   <span style="color: #666666; font-style: italic;"># 0</span>
<span style="color: #666666; font-style: italic;"># No error shown.</span>
<span style="color: #7a0874; font-weight: bold;">echo</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#  The above technique also comes in useful for commenting out</span>
<span style="color: #666666; font-style: italic;">#+ a block of working code for debugging purposes.</span>
<span style="color: #666666; font-style: italic;">#  This saves having to put a &quot;#&quot; at the beginning of each line,</span>
<span style="color: #666666; font-style: italic;">#+ then having to go back and delete each &quot;#&quot; later.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Just before commented-out code block.&quot;</span>
<span style="color: #666666; font-style: italic;">#  The lines of code between the double-dashed lines will not execute.</span>
<span style="color: #666666; font-style: italic;">#  ===================================================================</span>
: <span style="color: #cc0000; font-style: italic;">&lt;&lt;DEBUGXXX
for file in *
do
 cat &quot;$file&quot;
done
DEBUGXXX</span>
<span style="color: #666666; font-style: italic;">#  ===================================================================</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Just after commented-out code block.&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">######################################################################</span>
<span style="color: #666666; font-style: italic;">#  Note, however, that if a bracketed variable is contained within</span>
<span style="color: #666666; font-style: italic;">#+ the commented-out code block,</span>
<span style="color: #666666; font-style: italic;">#+ then this could cause problems.</span>
<span style="color: #666666; font-style: italic;">#  for example:</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#/!/bin/bash</span>
&nbsp;
  : <span style="color: #cc0000; font-style: italic;">&lt;&lt;COMMENTBLOCK
  echo &quot;This line will not echo.&quot;
  &amp;*@!!++=
  ${foo_bar_bazz?}
  $(rm -rf /tmp/foobar/)
  $(touch my_build_directory/cups/Makefile)
COMMENTBLOCK</span>
&nbsp;
&nbsp;
$ <span style="color: #c20cb9; font-weight: bold;">sh</span> commented-bad.sh
commented-bad.sh: line <span style="color: #000000;">3</span>: foo_bar_bazz: parameter null or not <span style="color: #000000; font-weight: bold;">set</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># The remedy for this is to strong-quote the 'COMMENTBLOCK' in line 49, above.</span>
&nbsp;
  : <span style="color: #000000; font-weight: bold;">&lt;&lt;</span><span style="color: #ff0000;">'COMMENTBLOCK'</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Thank you, Kurt Pfeifle, for pointing this out.</span></pre></div></div>

</pre>
</li>
<li><tt>自我文档化</tt>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># self-document.sh: self-documenting script</span>
<span style="color: #666666; font-style: italic;"># Modification of &quot;colm.sh&quot;.</span>
&nbsp;
<span style="color: #007800;">DOC_REQUEST</span>=<span style="color: #000000;">70</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$1&quot;</span> = <span style="color: #ff0000;">&quot;-h&quot;</span>  <span style="color: #660033;">-o</span> <span style="color: #ff0000;">&quot;$1&quot;</span> = <span style="color: #ff0000;">&quot;--help&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>     <span style="color: #666666; font-style: italic;"># Request help.</span>
<span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span>; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: $0 [directory-name]&quot;</span>; <span style="color: #7a0874; font-weight: bold;">echo</span>
  <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">--silent</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'/DOCUMENTATIONXX$/,/^DOCUMENTATIONXX$/p'</span> <span style="color: #ff0000;">&quot;$0&quot;</span> <span style="color: #000000; font-weight: bold;">|</span>
  <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'/DOCUMENTATIONXX$/d'</span>; <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$DOC_REQUEST</span>; <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
&nbsp;
: <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>DOCUMENTATIONXX
List the statistics of a specified directory <span style="color: #000000; font-weight: bold;">in</span> tabular format.
<span style="color: #660033;">---------------------------------------------------------------</span>
The command-line parameter gives the directory to be listed.
If no directory specified or directory specified cannot be <span style="color: #c20cb9; font-weight: bold;">read</span>,
<span style="color: #000000; font-weight: bold;">then</span> list the current working directory.
&nbsp;
DOCUMENTATIONXX
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #660033;">-o</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-r</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #007800;">directory</span>=.
<span style="color: #000000; font-weight: bold;">else</span>
  <span style="color: #007800;">directory</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>  
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Listing of &quot;</span><span style="color: #007800;">$directory</span><span style="color: #ff0000;">&quot;:&quot;</span>; <span style="color: #7a0874; font-weight: bold;">echo</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> \
; <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$directory</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> 1d<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">|</span> column <span style="color: #660033;">-t</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p>当然以上看上去很复杂的脚本，其实用cat也能实现
</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">DOC_REQUEST</span>=<span style="color: #000000;">70</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$1&quot;</span> = <span style="color: #ff0000;">&quot;-h&quot;</span>  <span style="color: #660033;">-o</span> <span style="color: #ff0000;">&quot;$1&quot;</span> = <span style="color: #ff0000;">&quot;--help&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>     <span style="color: #666666; font-style: italic;"># Request help.</span>
<span style="color: #000000; font-weight: bold;">then</span>                                       <span style="color: #666666; font-style: italic;"># Use a &quot;cat script&quot; . . .</span>
  <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>DOCUMENTATIONXX
List the statistics of a specified directory <span style="color: #000000; font-weight: bold;">in</span> tabular format.
<span style="color: #660033;">---------------------------------------------------------------</span>
The command-line parameter gives the directory to be listed.
If no directory specified or directory specified cannot be <span style="color: #c20cb9; font-weight: bold;">read</span>,
<span style="color: #000000; font-weight: bold;">then</span> list the current working directory.
&nbsp;
DOCUMENTATIONXX
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$DOC_REQUEST</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

</pre>
</li>
</ul>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2009/08/24/here-documents-in-bash.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2009/08/24/here-documents-in-bash.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>用shell升级15位身份证到18位</title>
		<link>http://blog.wgzhao.com/2009/08/20/15bit-id-card-upgrade-to-18bit-with-shell.html</link>
		<comments>http://blog.wgzhao.com/2009/08/20/15bit-id-card-upgrade-to-18bit-with-shell.html#comments</comments>
		<pubDate>Thu, 20 Aug 2009 10:03:58 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[技术技巧]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[身份证]]></category>

		<guid isPermaLink="false">http://mlsx.xplore.cn/?p=1833</guid>
		<description><![CDATA[写着好玩写的，纯粹是想知道最后那个校验码是怎么算出来的，具体的算法可以参考这里
更详细的例子，可以参考下面的链接：
http://www.heybrain.com/notheal/article/1138.html
我这里是用shell实现了，其实用C实现应该是最好的，毕竟算法的东西，C还是要快很多，我本是打算用C的，结果发现我都忘记得差不多了，连最简单的申明数组并初始化都忘记了，于是只要用效率比较低的shell，不过在做一些匹配和校验的时候，感觉比C要方便一些，不多说了，给代码

#!/bin/bash
#Description: Convert your 15bit old ID card into 18bit ID Card
#Author: mlsx mlsx.xplore(at) gmail.com
#Blog: http://mlsx.xplore.cn

crc=( 1 0 X 9 8 7 6 5 4 3 2 ) #CRC bit
weight=( 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ) #weight factor
oldcard=${1:-123}
while true
do
  echo $oldcard &#124;egrep -q [...]]]></description>
			<content:encoded><![CDATA[<p>写着好玩写的，纯粹是想知道最后那个校验码是怎么算出来的，具体的算法可以<a href="http://zh.wikipedia.org/wiki/%E6%A0%A1%E9%AA%8C%E7%A0%81">参考这里</a></p>
<p>更详细的例子，可以参考下面的链接：</p>
<p><a href="http://www.heybrain.com/notheal/article/1138.html">http://www.heybrain.com/notheal/article/1138.html</a></p>
<p>我这里是用shell实现了，其实用C实现应该是最好的，毕竟算法的东西，C还是要快很多，我本是打算用C的，结果发现我都忘记得差不多了，连最简单的申明数组并初始化都忘记了，于是只要用效率比较低的shell，不过在做一些匹配和校验的时候，感觉比C要方便一些，不多说了，给代码</p>
<p><span id="more-1833"></span></p>
<pre class="brush:bash">#!/bin/bash
#Description: Convert your 15bit old ID card into 18bit ID Card
#Author: mlsx mlsx.xplore(at) gmail.com
#Blog: http://mlsx.xplore.cn

crc=( 1 0 X 9 8 7 6 5 4 3 2 ) #CRC bit
weight=( 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ) #weight factor
oldcard=${1:-123}
while true
do
  echo $oldcard |egrep -q "^[0-9]{15}$"
  [ $? -eq 0 ] &amp;&amp; break
  echo -n "Pls hit your 15bit old ID card:"
  read oldcard
done

#insert two number "19" after sixth
tmpcard="`echo ${oldcard:0:6}`19`echo ${oldcard:6}`"

#split tmpcard into single digtial
y=0
for i in `echo {0..16}`
do
  a=${tmpcard:$i:1}
  (( y += $a * ${weight[$i]} ))
done

crcindex=`expr $y % 11`

echo "Your New 18bit ID Card is : ${tmpcard}${crc[$crcindex]}"

exit 0</pre>
<p>一个实际的例子如下：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ idcard.sh <span style="color: #000000;">340524800101001</span>
Your New 18bit ID Card is : 34052419800101001X</pre></div></div>

<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2009/08/20/15bit-id-card-upgrade-to-18bit-with-shell.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2009/08/20/15bit-id-card-upgrade-to-18bit-with-shell.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>bash里的一些控制字符</title>
		<link>http://blog.wgzhao.com/2009/08/15/some-control-characters-in-bash.html</link>
		<comments>http://blog.wgzhao.com/2009/08/15/some-control-characters-in-bash.html#comments</comments>
		<pubDate>Sat, 15 Aug 2009 12:39:25 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[abs]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[control character]]></category>

		<guid isPermaLink="false">http://mlsx.xplore.cn/?p=1821</guid>
		<description><![CDATA[摘自Advanced Bash-Scripting Guide V6.0.05第部分第三章的特殊字符中的片断，并做了翻译。

Ctl-A 将光标移到行首
Ctl-B 退格键（但是我在ubuntu 9.10 bash 3.2.48上测试却是向前移动光标，并不删除该字符）
Ctl-C 中断. 		  中断一个前台任务
Ctl-D 从当前shell退出（类似exit)EOF (end-of-file). 它也能中断在stdin的输入。
当在一个终端(console)或者虚拟终端(比如xterm)里敲键盘时，ctl-D 会删除当前光标下的字符.如果当前没有任何字符了，则 		  Ctl-D 表示从当前会话退出，如果时xterm之类的窗口，则会关闭当前窗口。
Ctl-E 移动光标到行末
Ctl-F 光标朝前移动一个字符位置
Ctl-G 响铃(BEL).在一些老式的电传(teletype)终端里，它可能真的会导致电话铃响起，而在xterm之类的终端里，只是发出一个声响。
Ctl-H 相当于退格键

#!/bin/bash
# Embedding Ctl-H in a string.
&#160;
a=&#34;^H^H&#34;                  # Two Ctl-H's -- backspaces
    [...]]]></description>
			<content:encoded><![CDATA[<p>摘自<a href="http://tldp.org/LDP/abs/html/" target="_blank">Advanced Bash-Scripting Guide V6.0.05</a>第部分第三章的<a href="http://tldp.org/LDP/abs/html/special-chars.html" target="_blank">特殊字符</a>中的片断，并做了翻译。</p>
<ul>
<li><tt><strong>Ctl-A </strong></tt>将光标移到行首</li>
<li><tt><strong>Ctl-B</strong></tt><tt><strong> 退格键（但是我在ubuntu 9.10 bash 3.2.48上测试却是向前移动光标，并不删除该字符）</strong></tt></li>
<li><tt><strong>Ctl-C</strong></tt><tt><strong> 中断</strong></tt>. 		  中断一个前台任务<span id="more-1821"></span></li>
<li><tt><strong>Ctl-D </strong></tt>从当前shell退出（类似exit)<tt><strong>EOF</strong></tt> (end-of-file). 它也能中断在stdin的输入。
<p>当在一个终端(console)或者虚拟终端(比如xterm)里敲键盘时，<tt><strong>ctl-D</strong></tt> 会删除当前光标下的字符.如果当前没有任何字符了，则 		  <tt><strong>Ctl-D</strong></tt> 表示从当前会话退出，如果时xterm之类的窗口，则会关闭当前窗口。</li>
<li><tt><strong>Ctl-E</strong></tt> 移动光标到行末</li>
<li><tt><strong>Ctl-F</strong></tt> 光标朝前移动一个字符位置</li>
<li><tt><strong>Ctl-G </strong></tt><tt><strong>响铃(BEL)</strong></tt>.在一些老式的电传(teletype)终端里，它可能真的会导致电话铃响起，而在xterm之类的终端里，只是发出一个声响。</li>
<li><tt><strong>Ctl-H</strong></tt> 相当于退格键

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># Embedding Ctl-H in a string.</span>
&nbsp;
<span style="color: #007800;">a</span>=<span style="color: #ff0000;">&quot;^H^H&quot;</span>                  <span style="color: #666666; font-style: italic;"># Two Ctl-H's -- backspaces</span>
                          <span style="color: #666666; font-style: italic;"># ctl-V ctl-H, using vi/vim</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;abcdef&quot;</span>             <span style="color: #666666; font-style: italic;"># abcdef</span>
<span style="color: #7a0874; font-weight: bold;">echo</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;abcdef<span style="color: #007800;">$a</span> &quot;</span>       <span style="color: #666666; font-style: italic;"># abcd f</span>
<span style="color: #666666; font-style: italic;">#  Space at end  ^              ^  Backspaces twice.</span>
<span style="color: #7a0874; font-weight: bold;">echo</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;abcdef<span style="color: #007800;">$a</span>&quot;</span>        <span style="color: #666666; font-style: italic;"># abcdef</span>
<span style="color: #666666; font-style: italic;">#  No space at end               ^ Doesn't backspace (why?).</span>
                          <span style="color: #666666; font-style: italic;"># Results may not be quite as expected.</span>
<span style="color: #7a0874; font-weight: bold;">echo</span>; <span style="color: #7a0874; font-weight: bold;">echo</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Constantin Hagemeier suggests trying:</span>
<span style="color: #666666; font-style: italic;"># a=$'\010\010'</span>
<span style="color: #666666; font-style: italic;"># a=$'\b\b'</span>
<span style="color: #666666; font-style: italic;"># a=$'\x08\x08'</span>
<span style="color: #666666; font-style: italic;"># But, this does not change the results.</span></pre></div></div>

</li>
<li><tt><strong>Ctl-I</strong></tt><tt><strong> 水平tab键</strong></tt>.</li>
<li><tt><strong>Ctl-J</strong></tt><tt><strong> 新行</strong></tt> (换行符).脚本里，也可能当八进制&#8217;\012&#8242;或十六进制符号&#8217;\x0a&#8217;解释。</li>
<li><tt><strong>Ctl-K</strong></tt><tt><strong> 垂直tab</strong></tt>当在console或者xterm窗口里键入文本时, 		  <tt><strong>Ctl-K</strong></tt> 表示删除从当前光标到行末的字符。在脚本里, 		  <tt><strong>Ctl-K</strong></tt> 的行为表现就不同的，具体的可以看下面 Lee Lee Maschmeyer的例子。</li>
<li><tt><strong>Ctl-L </strong></tt><tt><strong>换页</strong></tt> (终端清屏)。在终端里，其效果和<a href="http://tldp.org/LDP/abs/html/terminalccmds.html#CLEARREF">clear</a>命令类似(区别在于当前光标所在的行并不会清除) 。发送到打印机的话，<tt><strong>Ctl-L </strong></tt> 导致提前结束纸张。</li>
<li><tt><strong>Ctl-M </strong></tt><tt><strong>回车</strong></tt>.

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># Thank you, Lee Maschmeyer, for this example.</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #660033;">-s</span> <span style="color: #660033;">-p</span> \
$<span style="color: #ff0000;">'Control-M leaves cursor at beginning of this line. Press Enter. \x0d'</span>
           <span style="color: #666666; font-style: italic;"># Of course, '0d' is the hex equivalent of Control-M.</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>   <span style="color: #666666; font-style: italic;">#  The '-s' makes anything typed silent,</span>
           <span style="color: #666666; font-style: italic;">#+ so it is necessary to go to new line explicitly.</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #660033;">-s</span> <span style="color: #660033;">-p</span> $<span style="color: #ff0000;">'Control-J leaves cursor on next line. \x0a'</span>
           <span style="color: #666666; font-style: italic;">#  '0a' is the hex equivalent of Control-J, linefeed.</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
&nbsp;
<span style="color: #666666; font-style: italic;">###</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #660033;">-s</span> <span style="color: #660033;">-p</span> $<span style="color: #ff0000;">'And Control-K\x0bgoes straight down.'</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>   <span style="color: #666666; font-style: italic;">#  Control-K is vertical tab.</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># A better example of the effect of a vertical tab is:</span>
&nbsp;
<span style="color: #007800;">var</span>=$<span style="color: #ff0000;">'\x0aThis is the bottom line\x0bThis is the top line\x0a'</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$var</span>&quot;</span>
<span style="color: #666666; font-style: italic;">#  This works the same way as the above example. However:</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$var</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">col</span>
<span style="color: #666666; font-style: italic;">#  This causes the right end of the line to be higher than the left end.</span>
<span style="color: #666666; font-style: italic;">#  It also explains why we started and ended with a line feed --</span>
<span style="color: #666666; font-style: italic;">#+ to avoid a garbled screen.</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># As Lee Maschmeyer explains:</span>
<span style="color: #666666; font-style: italic;"># --------------------------</span>
<span style="color: #666666; font-style: italic;">#  In the [first vertical tab example] . . . the vertical tab</span>
<span style="color: #666666; font-style: italic;">#+ makes the printing go straight down without a carriage return.</span>
<span style="color: #666666; font-style: italic;">#  This is true only on devices, such as the Linux console,</span>
<span style="color: #666666; font-style: italic;">#+ that can't go &quot;backward.&quot;</span>
<span style="color: #666666; font-style: italic;">#  The real purpose of VT is to go straight UP, not down.</span>
<span style="color: #666666; font-style: italic;">#  It can be used to print superscripts on a printer.</span>
<span style="color: #666666; font-style: italic;">#  The col utility can be used to emulate the proper behavior of VT.</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

</li>
<li><tt><strong>Ctl-N</strong></tt> 从<em>history</em>指令缓冲里删除一行可重新调用的文本</li>
<li><tt><strong>Ctl-O</strong></tt> 发出一个新行</li>
<li><tt><strong>Ctl-P </strong></tt>重新调用<em>history</em>指令缓冲区调用最后一条指令</li>
<li><tt><strong>Ctl-Q</strong></tt> 恢复(<strong>XON</strong>)恢复终端的标准输入(stdin)</li>
<li><tt><strong>Ctl-R </strong></tt>向后搜索<em>history</em>指令缓冲文本</li>
<li><tt><strong>Ctl-S</strong></tt> 暂停 (<tt><strong>XOFF</strong></tt>).冻结终端的标准输入(用ctl-Q来恢复)</li>
<li><tt><strong>Ctl-T </strong></tt>将当前光标位置的字符和光标前的字符进行位置交换</li>
<li><tt><strong>Ctl-U</strong></tt> 删除从行首到当前光标位置的字符(不包括当前光标位置的字符).在默写设置下, 		  <tt><strong>Ctl-U</strong></tt> 删除整行，而不管光标位置</li>
<li><tt><strong>Ctl-V</strong></tt> 输入文本的时候， <tt><strong>Ctl-V</strong></tt> 允许插入控制字符，下面例子的两条指令效果是相同的

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'\x0a'</span>
<span style="color: #7a0874; font-weight: bold;">echo</span></pre></div></div>

<p><tt><strong>Ctl-V</strong></tt> 主要在文本编辑器里起作用</li>
<li><tt><strong>Ctl-W</strong></tt> 在终端(console)或者类似xterm窗口里输入文本时， 		  <tt><strong>Ctl-W</strong></tt> 删除从当前光标位置到之前的第一个空格之间的字符。在某些设置下， <tt><strong>Ctl-W</strong></tt> 向后删除到第一个非字母数字字符</li>
<li><tt><strong>Ctl-Z</strong></tt> 暂停前台任务</li>
</ul>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2009/08/15/some-control-characters-in-bash.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2009/08/15/some-control-characters-in-bash.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用bash校验IP地址</title>
		<link>http://blog.wgzhao.com/2008/06/30/check-ip-address-with-bash.html</link>
		<comments>http://blog.wgzhao.com/2008/06/30/check-ip-address-with-bash.html#comments</comments>
		<pubDate>Mon, 30 Jun 2008 01:18:57 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[技术技巧]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[validate]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=946</guid>
		<description><![CDATA[代码：

#!/bin/bash
&#160;
# Test an IP address for validity:
# Usage:
#      valid_ip IP_ADDRESS
#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi
#   OR
#      if valid_ip IP_ADDRESS; then echo good; else echo bad; fi
#
function valid_ip&#40;&#41;
&#123;
local  ip=$1
local  [...]]]></description>
			<content:encoded><![CDATA[<p>代码：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Test an IP address for validity:</span>
<span style="color: #666666; font-style: italic;"># Usage:</span>
<span style="color: #666666; font-style: italic;">#      valid_ip IP_ADDRESS</span>
<span style="color: #666666; font-style: italic;">#      if [[ $? -eq 0 ]]; then echo good; else echo bad; fi</span>
<span style="color: #666666; font-style: italic;">#   OR</span>
<span style="color: #666666; font-style: italic;">#      if valid_ip IP_ADDRESS; then echo good; else echo bad; fi</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #000000; font-weight: bold;">function</span> valid_ip<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #7a0874; font-weight: bold;">local</span>  <span style="color: #007800;">ip</span>=$<span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">local</span>  <span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">stat</span></span>=<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$ip</span> =~ ^<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>\.<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>\.<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>\.<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>$ <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
<span style="color: #007800;">OIFS</span>=<span style="color: #007800;">$IFS</span>
<span style="color: #007800;">IFS</span>=<span style="color: #ff0000;">'.'</span>
<span style="color: #007800;">ip</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$ip</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">IFS</span>=<span style="color: #007800;">$OIFS</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #800000;">${ip[0]}</span> <span style="color: #660033;">-le</span> <span style="color: #000000;">255</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #800000;">${ip[1]}</span> <span style="color: #660033;">-le</span> <span style="color: #000000;">255</span> \
<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #800000;">${ip[2]}</span> <span style="color: #660033;">-le</span> <span style="color: #000000;">255</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #800000;">${ip[3]}</span> <span style="color: #660033;">-le</span> <span style="color: #000000;">255</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">stat</span></span>=<span style="color: #007800;">$?</span>
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #007800;">$stat</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># If run directly, execute some tests.</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(basename $0 .sh)</span>&quot;</span> == <span style="color: #ff0000;">'valid_ip'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
<span style="color: #007800;">ips</span>=<span style="color: #ff0000;">'
4.2.2.2
a.b.c.d
192.168.1.1
0.0.0.0
255.255.255.255
255.255.255.256
192.168.0.1
192.168.0
1234.123.123.123
'</span>
<span style="color: #000000; font-weight: bold;">for</span> ip <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$ips</span>
<span style="color: #000000; font-weight: bold;">do</span>
<span style="color: #000000; font-weight: bold;">if</span> valid_ip <span style="color: #007800;">$ip</span>; <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">stat</span></span>=<span style="color: #ff0000;">'good'</span>; <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">stat</span></span>=<span style="color: #ff0000;">'bad'</span>; <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;%-20s: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$ip</span>&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$stat</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>测试：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># sh valid_ip.sh</span>
4.2.2.2             : good
a.b.c.d             : bad
192.168.1.1         : good
0.0.0.0             : good
255.255.255.255     : good
255.255.255.256     : bad
192.168.0.1         : good
192.168.0           : bad
1234.123.123.123    : bad</pre></div></div>

<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2008/06/30/check-ip-address-with-bash.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2008/06/30/check-ip-address-with-bash.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bash里面计算的几种方法</title>
		<link>http://blog.wgzhao.com/2005/06/02/bash-there-are-several-ways-of-calculating.html</link>
		<comments>http://blog.wgzhao.com/2005/06/02/bash-there-are-several-ways-of-calculating.html#comments</comments>
		<pubDate>Thu, 02 Jun 2005 11:31:16 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[计算]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=85</guid>
		<description><![CDATA[#!/bin/bashn=1;echo -n "$n "

let "n = $n + 1" #note: let "n = n + 1" also worksecho -n "$n "

: $((n=$n+1))# ":" necessary beacause otherwise bash attempts# + to interpret "$((n=$n+1))" as a commandecho -n "$n "

n=$(($n + 1 ))echo -n "$n "

: $[ n = $n + 1 ]echo -n "$n "

n=$[ $n [...]]]></description>
			<content:encoded><![CDATA[<pre class="code">#!/bin/bashn=1;echo -n "$n "

let "n = $n + 1" #note: let "n = n + 1" also worksecho -n "$n "

: $((n=$n+1))# ":" necessary beacause otherwise bash attempts# + to interpret "$((n=$n+1))" as a commandecho -n "$n "

n=$(($n + 1 ))echo -n "$n "

: $[ n = $n + 1 ]echo -n "$n "

n=$[ $n + 1 ]echo -n "$n "echo &nbsp;-e

exit 0

</pre>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2005/06/02/bash-there-are-several-ways-of-calculating.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2005/06/02/bash-there-are-several-ways-of-calculating.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>求最大公约数的bash脚本</title>
		<link>http://blog.wgzhao.com/2005/06/02/The-common-denominator-for-the-bash-script.html</link>
		<comments>http://blog.wgzhao.com/2005/06/02/The-common-denominator-for-the-bash-script.html#comments</comments>
		<pubDate>Thu, 02 Jun 2005 11:20:29 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[最大公约数]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=86</guid>
		<description><![CDATA[#!/bin/bash#greatest common divisorARGS=2E_BADARGS=65if [ $# -ne "$ARGS" ]then &#160; &#160; &#160; &#160;echo "Usage: &#96;basename $0&#96; first-interage second-interage" &#160; &#160; &#160; &#160;exit $E_BADARGS;fi

gcd(){ &#160; &#160; &#160; &#160;diviend=$1 &#160; &#160; &#160; &#160;divisor=$2 &#160; &#160; &#160; &#160;until [ ! $diviend -ne $divisor ] &#160; &#160; &#160; &#160;do &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;if [ $diviend -lt [...]]]></description>
			<content:encoded><![CDATA[<pre>#!/bin/bash#greatest common divisorARGS=2E_BADARGS=65if [ $# -ne "$ARGS" ]then &nbsp; &nbsp; &nbsp; &nbsp;echo "Usage: &#96;basename $0&#96; first-interage second-interage" &nbsp; &nbsp; &nbsp; &nbsp;exit $E_BADARGS;fi

gcd(){ &nbsp; &nbsp; &nbsp; &nbsp;diviend=$1 &nbsp; &nbsp; &nbsp; &nbsp;divisor=$2 &nbsp; &nbsp; &nbsp; &nbsp;until [ ! $diviend -ne $divisor ] &nbsp; &nbsp; &nbsp; &nbsp;do &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if [ $diviend -lt $divisor ] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;temp=$diviend &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;diviend=$divisor &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;divisor=$temp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fi &nbsp; &nbsp; &nbsp; &nbsp;let "diviend=$diviend - $divisor"; &nbsp; &nbsp; &nbsp; &nbsp;done}gcd $1 $2echo ; echo "GCD of $1 and $2 = $diviend"; echoexit 0
</pre>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2005/06/02/The-common-denominator-for-the-bash-script.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2005/06/02/The-common-denominator-for-the-bash-script.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一些bash编程中常犯的错误！</title>
		<link>http://blog.wgzhao.com/2005/05/31/some-of-the-programming-bash-often-mistake.html</link>
		<comments>http://blog.wgzhao.com/2005/05/31/some-of-the-programming-bash-often-mistake.html#comments</comments>
		<pubDate>Tue, 31 May 2005 08:10:55 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[常见错误]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=88</guid>
		<description><![CDATA[注意！！！！这里面的例子全部是错误的！！！=====变量使用=====1.将bash保留字符串定义为变量名/变量名中含有保留字符case=123 #case是保留字串
ca((=123 #((是保留字符
var-1=123 #-是保留字符，用var_1好了2.变量用数字开头 &#160; 12var=123   &#160;3.变量与函数定义重名代码: &#160; &#160;do_something ()
{
  echo &#8220;This function does something with &#8220;$1&#8243;.&#8221;
}
do_something=do_something
do_something do_something4.变量赋值=两边有空格var1 = 123 # var1=123才行    ====================比较[]=====5.[]内缺少空格代码: &#160; &#160;[$var -eq 5 ]
[ $var=ab ]6.使用时不加代码: &#160; &#160;[ $var < ab ] #这时被解释为输出重定向，[ $var < ab ]才对7.=>]]></description>
			<content:encoded><![CDATA[<p>注意！！！！这里面的例子全部是错误的！！！<br/><br/>=====变量使用=====<br/>1.将bash保留字符串定义为变量名/变量名中含有保留字符<br/><br/><coolcode>case=123 #case是保留字串<br />
ca((=123 #((是保留字符<br />
var-1=123 #-是保留字符，用var_1好了</coolcode><br/><span id="more-88"></span><br/>2.变量用数字开头<br/> &nbsp; <br/><coolcode>12var=123  </coolcode> &nbsp;<br/><br/>3.变量与函数定义重名<br/><br/>代码: &nbsp; &nbsp;<br/><br/><coolcode>do_something ()<br />
{<br />
  echo &#8220;This function does something with &#8220;$1&#8243;.&#8221;<br />
}</p>
<p>do_something=do_something</p>
<p>do_something do_something</coolcode><br/><br/><br/>4.变量赋值=两边有空格<br/><coolcode>var1 = 123 # var1=123才行    </coolcode><br/><br/><br/>===============<br/>=====比较[]=====<br/>5.[]内缺少空格<br/>代码: &nbsp; &nbsp;<br/><br/><coolcode>[$var -eq 5 ]<br />
[ $var=ab ]</coolcode><br/><br/>6.<>使用时不加<br/>代码: &nbsp; &nbsp;<br/><br/>[ $var < ab ] #这时<>被解释为输出重定向，[ $var < ab ]才对<br/><br/>7.=><与 -eq -gt -lt不分<br/>代码: &nbsp; &nbsp;<br/><br/>[ $var -eq 45.6 ] #=><用来比较字串，而eq gt lt只能用来比较整数，注意是整数，不是数值<br/><br/>=================<br/>8.脚本的sha-bang中不能有非法字符，用dos/win中写的东西是以rn换行的，脚本第1行实际是 #!/bin/bashrn，而只有#!/bin/bashn才是合法的<br/>运行时会给出这样的错误<br/>: bad interpreter: 没有那个文件或目录<br/><br/>9.子shell中对变量的操作是不能传递给它的父shell<br/><coolcode>var=123<br />
( $var=456 )<br />
echo $var #结果是123而不是456<br />
echo 456&#124;read var<br />
echo $var #结果还是123，管道是会发起子shell的</coolcode></p>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2005/05/31/some-of-the-programming-bash-often-mistake.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2005/05/31/some-of-the-programming-bash-often-mistake.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bash编程(3)</title>
		<link>http://blog.wgzhao.com/2004/12/10/bash-programming-3.html</link>
		<comments>http://blog.wgzhao.com/2004/12/10/bash-programming-3.html#comments</comments>
		<pubDate>Thu, 09 Dec 2004 17:28:33 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=164</guid>
		<description><![CDATA[进入 ebuild 系统我真是一直期待着这第三篇、也是最后一篇 Bash实例文章，因为既然已经在第1篇和第2篇中讲述了 bash 编程基础，就可以集中讲述象 bash应用开发和程序设计这样更高级的主题。在本文中，将通过我花了许多时间来编码和细化的项目，GentooLinux ebuild 系统，来给您大量实际的、现实世界的 bash 开发经验。我是 Gentoo Linux（目前还是 beta 版的下一代 Linux OS）的首席设计师。我的主要责任之一就是确保所有二进制包（类似于RPM）都正确创建并一起使用。正如您可能知道的，标准 Linux系统不是由一棵统一的源树组成（象 BSD），而实际上是由超过 25个协同工作的核心包组成。这其中包括：包 &#160;描述linux &#160;实际内核util-linux &#160;与 Linux 相关的杂项程序集合e2fsprogs &#160;与 ext2 文件系统相关的实用程序集合glibc &#160;GNU C 库每个包都位于各自的 tar压缩包中，并由不同的独立开发人员或开发小组维护。要创建一个发行版，必须对每个包分别进行下载、编译和打包处理。每次要修复、升级或改进包时，都必须重复编译和打包步骤（并且，包确实更新得很快）。为了帮助消除创建和更新包所涉及的重复步骤，我创建了ebuild 系统，该系统几乎全用 bash 编写。为了增加您的 bash知识，我将循序渐进地为您演示如何实现该 ebuild系统的解包和编译部分。在解释每一步时，还将讨论为什么要作出某些设计决定。在本文末尾，您不仅将极好地掌握大型bash 编程项目，还实现了完整自动构建系统的很大一部分。为什么选择 bash？Bash 是 Gentoo Linux ebuild 系统的基本组件。选择它做为 ebuild的主要语言有几个原因。首先，其语法不复杂，并且为人们所熟悉，这特别适合于调用外部程序。自动构建系统是自动调用外部程序的“胶合代码”，而bash 非常适合于这种类型的应用。第二，Bash 对函数的支持允许 ebuild系统使用模块化、易于理解的代码。第三，ebuild 系统利用了 bash对环境变量的支持，允许包维护人员和开发人员在运行时对其进行方便的在线配置。构建过程回顾在讨论 ebuild系统之前，让我们回顾一下编译和安装包都牵涉些什么。例如，让我们看一下&#8221;sed&#8221; 包，这个作为所有 Linux 版本一部分的标准 GNU文本流编辑实用程序。首先，下载源代码 [...]]]></description>
			<content:encoded><![CDATA[<p>进入 ebuild 系统<br/>我真是一直期待着这第三篇、也是最后一篇 Bash实例文章，因为既然已经在第1篇和第2篇中讲述了 bash 编程基础，就可以集中讲述象 bash应用开发和程序设计这样更高级的主题。在本文中，将通过我花了许多时间来编码和细化的项目，GentooLinux ebuild 系统，来给您大量实际的、现实世界的 bash 开发经验。<br/><span id="more-164"></span><br/>我是 Gentoo Linux（目前还是 beta 版的下一代 Linux OS）的首席设计师。我的主要责任之一就是确保所有二进制包（类似于RPM）都正确创建并一起使用。正如您可能知道的，标准 Linux系统不是由一棵统一的源树组成（象 BSD），而实际上是由超过 25个协同工作的核心包组成。这其中包括：<br/>包 &nbsp;描述<br/>linux &nbsp;实际内核<br/>util-linux &nbsp;与 Linux 相关的杂项程序集合<br/>e2fsprogs &nbsp;与 ext2 文件系统相关的实用程序集合<br/>glibc &nbsp;GNU C 库<br/><br/>每个包都位于各自的 tar压缩包中，并由不同的独立开发人员或开发小组维护。要创建一个发行版，必须对每个包分别进行下载、编译和打包处理。每次要修复、升级或改进包时，都必须重复编译和打包步骤（并且，包确实更新得很快）。为了帮助消除创建和更新包所涉及的重复步骤，我创建了ebuild 系统，该系统几乎全用 bash 编写。为了增加您的 bash知识，我将循序渐进地为您演示如何实现该 ebuild系统的解包和编译部分。在解释每一步时，还将讨论为什么要作出某些设计决定。在本文末尾，您不仅将极好地掌握大型bash 编程项目，还实现了完整自动构建系统的很大一部分。<br/><br/>为什么选择 bash？<br/>Bash 是 Gentoo Linux ebuild 系统的基本组件。选择它做为 ebuild的主要语言有几个原因。首先，其语法不复杂，并且为人们所熟悉，这特别适合于调用外部程序。自动构建系统是自动调用外部程序的“胶合代码”，而bash 非常适合于这种类型的应用。第二，Bash 对函数的支持允许 ebuild系统使用模块化、易于理解的代码。第三，ebuild 系统利用了 bash对环境变量的支持，允许包维护人员和开发人员在运行时对其进行方便的在线配置。<br/><br/>构建过程回顾<br/>在讨论 ebuild系统之前，让我们回顾一下编译和安装包都牵涉些什么。例如，让我们看一下&#8221;sed&#8221; 包，这个作为所有 Linux 版本一部分的标准 GNU文本流编辑实用程序。首先，下载源代码 tar 压缩包(sed-3.02.tar.gz)。我们将把这个档案存储在/usr/src/distfiles 中，将使用环境变量 &#8220;$DISTDIR&#8221;来引用该目录。&#8221;$DISTDIR&#8221; 是所有原始源代码 tar压缩包所在的目录，它是一个大型源代码库。<br/><br/>下一步是创建名为 &#8220;work&#8221;的临时目录，该目录存放已经解压的源代码。以后将使用 &#8220;$WORKDIR&#8221;环境变量引用该目录。要做到这点，进入有写权限的目录，然后输入：<br/><br/>将 sed 解压缩到临时目录<br/><br/>$ mkdir work<br/>$ cd work<br/>$ tar xzf /usr/src/distfiles/sed-3.02.tar.gz<br/><br/>然后，解压缩 tar 压缩包，创建一个包含所有源代码、名为 sed-3.02的目录。以后将使用环境变量 &#8220;$SRCDIR&#8221; 引用 sed-3.02目录。要编译程序，输入：<br/><br/>将 sed 解压缩到临时目录<br/><br/>$ cd sed-3.02<br/>$ ./configure &#8211;prefix=/usr<br/>（autoconf 生成适当的 make 文件，这要花一些时间）<br/><br/>$ make<br/><br/>(从源代码编译包，也要花一点时间）<br/><br/>因为在本文中只讲述解包和编译步骤，所以将略过 &#8220;make install&#8221;步骤。如果要编写 bash脚本来执行所有这些步骤，则代码可能类似于：<br/><br/>要执行解包／编译过程的样本 bash 脚本<br/><br/><coolcode>#!/usr/bin/env bash</p>
<p>if [ -d work ]<br />
then<br />
# remove old work directory if it exists<br />
    rm -rf work<br />
fi<br />
mkdir work<br />
cd work<br />
tar xzf /usr/src/distfiles/sed-3.02.tar.gz<br />
cd sed-3.02<br />
./configure &#8211;prefix=/usr<br />
make</coolcode><br/><br/>使代码通用<br/>虽然可以使用这个自动编译脚本，但它不是很灵活。基本上，bash脚本只包含在命令行输入的所有命令列表。虽然可以使用这种解决方案，但是，最好做一个只通过更改几行就可以快速解包和编译任何包的适用脚本。这样，包维护人员将新包添加到发行版所需的工作就大为减少。让我们先尝试一下使用许多不同的环境变量来完成，使构建脚本更加适用：<br/><br/>新的、更通用的脚本<br/><coolcode><br />
#!/usr/bin/env bash</p>
<p># P is the package name</p>
<p>P=sed-3.02</p>
<p># A is the archive name</p>
<p>A=${P}.tar.gz</p>
<p>export ORIGDIR=&#96;pwd&#96;<br />
export WORKDIR=${ORIGDIR}/work<br />
export SRCDIR=${WORKDIR}/${P}</p>
<p>if [ -z "$DISTDIR" ]<br />
then<br />
    # set DISTDIR to /usr/src/distfiles if not already set<br />
    DISTDIR=/usr/src/distfiles<br />
fi<br />
export DISTDIR</p>
<p>if [ -d ${WORKDIR} ]<br />
then<br />
    # remove old work directory if it exists<br />
    rm -rf ${WORKDIR}<br />
fi</p>
<p>mkdir ${WORKDIR}<br />
cd ${WORKDIR}<br />
tar xzf ${DISTDIR}/${A}<br />
cd ${SRCDIR}<br />
./configure &#8211;prefix=/usr<br />
make</coolcode><br/><br/>已经向代码中添加了很多环境变量，但是，它基本上还是执行同一功能。但是，如果现在要要编译任何标准的GNU 基于 autoconf 的源代码 tar压缩包，只需简单地将该文件复制到一个新文件（用合适的名称来反映它所编译的新包名），然后将&#8221;$A&#8221; 和 &#8220;$P&#8221;的值更改成新值即可。所有其它环境变量都自动调整成正确设置，并且脚本按预想工作。虽然这很方便，但是代码还有改进余地。这段代码比我们开始创建的&#8221;transcript&#8221;脚本要长很多。既然任何编程项目的目标之一是减少用户复杂度，所以最好大幅度缩短代码，或者至少更好地组织代码。可以用一个巧妙的方法来做到这点&#8211; 将代码拆成两个单独文件。将该文件存为 &#8220;sed-3.02.ebuild&#8221;：<br/><br/>sed-3.02.ebuild<br/><br/>#the sed ebuild file &#8212; very simple!<br/>P=sed-3.02<br/>A=${P}.tar.gz<br/> &nbsp; <br/><br/>第一个文件不重要，只包含那些必须在每个包中配置的环境变量。下面是第二个文件，它包含操作的主要部分。将它存为&#8221;ebuild&#8221;，并使它成为可执行文件：<br/><br/>ebuild 脚本<br/><br/><coolcode>#!/usr/bin/env bash</p>
<p>if [ $# -ne 1 ]<br />
then<br />
    echo &#8220;one argument expected.&#8221;<br />
    exit 1<br />
fi</p>
<p>if [ -e "$1" ]<br />
then<br />
    source $1<br />
else<br />
    echo &#8220;ebuild file $1 not found.&#8221;<br />
    exit 1<br />
fi</p>
<p>export ORIGDIR=&#96;pwd&#96;<br />
export WORKDIR=${ORIGDIR}/work<br />
export SRCDIR=${WORKDIR}/${P}</p>
<p>if [ -z "$DISTDIR" ]<br />
then<br />
    # set DISTDIR to /usr/src/distfiles if not already set<br />
    DISTDIR=/usr/src/distfiles<br />
fi<br />
export DISTDIR</p>
<p>if [ -d ${WORKDIR} ]<br />
then<br />
    # remove old work directory if it exists<br />
    rm -rf ${WORKDIR}<br />
fi</p>
<p>mkdir ${WORKDIR}<br />
cd ${WORKDIR}<br />
tar xzf ${DISTDIR}/${A}<br />
cd ${SRCDIR}<br />
./configure &#8211;prefix=/usr<br />
make</coolcode><br/><br/>既然已经将构建系统拆成两个文件，我敢打赌，您一定在想它的工作原理。基本上，要编译sed，输入：<br/><br/>$ ./ebuild sed-3.02.ebuild<br/><br/>当执行 &#8220;ebuild&#8221; 时，它首先试图 &#8220;source&#8221; 变量&#8221;$1&#8243;。这是什么意思？还记得前一篇文章所讲的吗：&#8221;$1&#8243; 是第一个命令行自变量 &#8212; 在这里，是&#8221;sed-3.02.ebuild&#8221;。在 bash 中，&#8221;source&#8221; 命令从文件中读入 bash语句，然后执行它们，就好象它们直接出现在 &#8220;source&#8221;命令所在的文件中一样。因此，&#8221;source ${1}&#8221; 导致 &#8220;ebuild&#8221; 脚本执行在&#8221;sed-3.02.ebuild&#8221; 中定义 &#8220;$P&#8221; 和 &#8220;$A&#8221;的命令。这种设计更改确实方便，因为如果要编译另一个程序，而不是sed，可以简单地创建一个新的 .ebuild 文件，然后将其作为自变量传递给&#8221;ebuild&#8221; 脚本。通过这种方式，.ebuild 文件最终非常简单，而将 ebuild系统复杂的操作部分存在一处，即 &#8220;ebuild&#8221;脚本中。通过这种方式，只需编辑 &#8220;ebuild&#8221; 脚本就可以升级或增强 ebuild系统，同时将实现细节保留在 ebuild 文件之外。这里有一个 gzip 的样本ebuild 文件：<br/><br/>gzip-1.2.4a.ebuild<br/><br/>#another really simple ebuild script!<br/>P=gzip-1.2.4a<br/>A=${P}.tar.gz<br/><br/>添加功能性<br/>好，我们正在取得进展。但是，我还想添加某些额外功能性。我希望 ebuild脚本再接受一个命令行自变量：&#8221;compile&#8221;、&#8221;unpack&#8221; 或&#8221;all&#8221;。这个命令行自变量告诉 ebuild脚本要执行构建过程的哪一步。通过这种方式，可以告诉 ebuild解包档案，但不进行编译（以便在开始编译之前查看源代码档案）。要做到这点，将添加一条case 语句，该语句将测试&#8221;$2&#8243;，然后根据其值执行不同操作。代码如下：<br/><br/>ebuild，修定本 2<br/><br/><coolcode>#!/usr/bin/env bash</p>
<p>if [ $# -ne 2 ]<br />
then<br />
    echo &#8220;Please specify two args &#8211; .ebuild file and unpack, compile or all&#8221;<br />
    exit 1<br />
fi</p>
<p>if [ -z "$DISTDIR" ]<br />
then<br />
    # set DISTDIR to /usr/src/distfiles if not already set<br />
    DISTDIR=/usr/src/distfiles<br />
fi<br />
export DISTDIR</p>
<p>ebuild_unpack() {<br />
    #make sure we&#039;re in the right directory<br />
    cd ${ORIGDIR}</p>
<p>    if [ -d ${WORKDIR} ]<br />
    then<br />
        rm -rf ${WORKDIR}<br />
    fi</p>
<p>    mkdir ${WORKDIR}<br />
    cd ${WORKDIR}<br />
    if [ ! -e ${DISTDIR}/${A} ]<br />
    then<br />
        echo &#8220;${DISTDIR}/${A} does not exist.  Please download first.&#8221;<br />
        exit 1<br />
    fi<br />
    tar xzf ${DISTDIR}/${A}<br />
    echo &#8220;Unpacked ${DISTDIR}/${A}.&#8221;<br />
    #source is now correctly unpacked<br />
}</p>
<p>ebuild_compile() {</p>
<p>    #make sure we&#039;re in the right directory<br />
    cd ${SRCDIR}<br />
    if [ ! -d "${SRCDIR}" ]<br />
    then<br />
        echo &#8220;${SRCDIR} does not exist &#8212; please unpack first.&#8221;<br />
        exit 1<br />
        fi<br />
    ./configure &#8211;prefix=/usr<br />
    make<br />
}</p>
<p>export ORIGDIR=&#96;pwd&#96;<br />
export WORKDIR=${ORIGDIR}/work</p>
<p>if [ -e "$1" ]<br />
then<br />
    source $1<br />
else<br />
    echo &#8220;Ebuild file $1 not found.&#8221;<br />
    exit 1<br />
fi</p>
<p>export SRCDIR=${WORKDIR}/${P}</p>
<p>case &#8220;${2}&#8221; in<br />
    unpack)<br />
        ebuild_unpack<br />
        ;;<br />
    compile)<br />
        ebuild_compile<br />
        ;;<br />
    all)<br />
        ebuild_unpack<br />
        ebuild_compile<br />
        ;;<br />
    *)<br />
        echo &#8220;Please specify unpack, compile or all as the second arg&#8221;<br />
        exit 1<br />
        ;;<br />
esac</coolcode><br/><br/><br/><br/>已经做了很多改动，下面来回顾一下。首先，将编译和解包步骤放入各自的函数中，其函数名分别为ebuild_compile() 和ebuild_unpack()。这是个好的步骤，因为代码正变得越来越复杂，而新函数提供了一定的模块性，使代码更有条理。在每个函数的第一行，显式 &#8220;cd&#8221;到想要的目录，因为，随着代码变得越来越模块化而不是线形化，出现疏忽而在错误的当前工作目录中执行函数的可能性也变大。&#8221;cd&#8221;命令显式地使我们处于正确的位置，并防止以后出现错误 -这是重要的步骤，特别是在函数中删除文件时更是如此。<br/><br/>另外，还在 ebuild_compile()函数的开始处添加了一个有用的检查。现在，它检查以确保 &#8220;$SRCDIR&#8221;存在，如果不存在，则打印一条告诉用户首先解包档案然后退出的错误消息。如果愿意，可以改变这种行为，以便在&#8221;$SRCDIR&#8221; 不存在的情况下，ebuild脚本将自动解包源代码档案。可以用以下代码替换 ebuild_compile()来做到这点：<br/><br/>ebuild_compile() 上的新代码<br/><br/><coolcode>ebuild_compile() {<br />
    #make sure we&#039;re in the right directory<br />
    if [ ! -d "${SRCDIR}" ]<br />
    then<br />
        ebuild_unpack<br />
        fi<br />
    cd ${SRCDIR}<br />
    ./configure &#8211;prefix=/usr<br />
    make<br />
}</coolcode><br/><br/>ebuild 脚本第二版中最明显的改动之一就是代码末尾新的 case语句。这条 case语句只是检查第二个命令行自变量，然后根据其值执行正确操作。如果现在输入：<br/><br/>$ ebuild sed-3.02.ebuild<br/><br/>就会得到一条错误消息。现在需要告诉 ebuild 做什么，如下所示：<br/><br/>$ ebuild sed-3.02.ebuild unpack<br/><br/>或<br/><br/>$ ebuild sed-3.02.ebuild compile<br/><br/>或<br/><br/>$ ebuild sed-3.02.ebuild all<br/><br/>如果提供上面所列之外的第二个命令行自变量，将得到一条错误消息（*子句），然后，程序退出。<br/><br/>使代码模块化<br/>既然代码很高级并且实用，您可能很想创建几个更高级的 ebuild脚本，以解包和编译所喜爱的程序。如果这样做，迟早会遇到一些不使用autoconf (&#8220;./configure&#8221;)的源代码，或者可能遇到其它使用非标准编译过程的脚本。需要再对 ebuild系统做一些改动，以适应这些程序。但是在做之前，最好先想一下如何完成。<br/><br/>将 &#8220;./configure &#8211;prefix=/usr; make&#8221;硬编码到编译阶段的妙处之一是：大多数时候，它可以正确工作。但是，还必须使ebuild 系统适应那些不使用 autoconf 或正常 make文件的源代码。要解决这个问题，建议 ebuild脚本缺省执行以下操作：<br/><br/> &nbsp; 1. 如果在 &#8220;${SRCDIR}&#8221; 中有一个配置脚本，则按如下执行它：<br/> &nbsp; &nbsp; &nbsp;./configure &#8211;prefix=/usr<br/> &nbsp; &nbsp; &nbsp;否则，跳过这步。<br/><br/> &nbsp; 2. 执行以下命令：<br/> &nbsp; &nbsp; &nbsp;make<br/><br/>既然 ebuild 只在 configure实际存在时才运行它，现在可以自动地适应那些不使用 autoconf 但有标准make 文件的程序。但是，在简单的 &#8220;make&#8221;对某些源代码无效时该怎么办？需要一些处理这些情况的特定代码来覆盖合理的缺省值。要做到这一点，将把ebuild_compile()函数转换成两个函数。第一个函数（可将其当成“父”函数）的名称仍是ebuild_compile()。但是，将有一个名为 user_compile()的新函数，该函数只包含合理的缺省操作：<br/><br/>拆成两个函数的 ebuild_compile()<br/><br/><coolcode>user_compile() {<br />
    #we&#039;re already in ${SRCDIR}<br />
    if [ -e configure ]<br />
    then<br />
        #run configure script if it exists<br />
        ./configure &#8211;prefix=/usr<br />
    fi<br />
    #run make<br />
    make<br />
}          </p>
<p>ebuild_compile() {<br />
    if [ ! -d "${SRCDIR}" ]<br />
    then<br />
        echo &#8220;${SRCDIR} does not exist &#8212; please unpack first.&#8221;<br />
        exit 1<br />
    fi<br />
    #make sure we&#039;re in the right directory<br />
    cd ${SRCDIR}<br />
    user_compile<br />
}</coolcode><br/><br/>现在这样做的原因可能还不是很明显，但是，再忍耐一下。虽然这段代码与ebuild 前一版的工作方式几乎相同，但是现在可以做一些以前无法做的 &#8211;可以在 sed-3.02.ebuild 中覆盖 user_compile()。因此，如果缺省的user_compile() 不满足要求，可以在 .ebuild文件中定义一个新的，使其包含编译包所必需的命令。例如，这里有一个e2fsprogs-1.18 的 ebuild 文件，它需要一个略有不同的 &#8220;./configure&#8221;行：<br/><br/><coolcode>e2fsprogs-1.18.ebuild</p>
<p>#this ebuild file overrides the default user_compile()<br />
P=e2fsprogs-1.18<br />
A=${P}.tar.gz</p>
<p>user_compile() {<br />
       ./configure &#8211;enable-elf-shlibs<br />
       make<br />
}</coolcode><br/><br/>现在，将完全按照我们希望的方式编译e2fsprogs。但是，对于大多数包来说，可以省略 .ebuild文件中的任何定制 user_compile() 函数，而使用缺省的 user_compile()函数。<br/><br/>ebuild 脚本又怎样知道要使用哪个 user_compile()函数呢？实际上，这很简单。ebuild 脚本中，在执行e2fsprogs-1.18.ebuild 文件之前定义缺省 user_compile() 函数。如果在e2fsprogs-1.18.ebuild 中有一个user_compile()，则它覆盖前面定义的缺省版本。如果没有，则使用缺省user_compile() 函数。<br/><br/>这是好工具，我们已经添加了很多灵活性，而无需任何复杂代码（如果不需要的话）。在这里就不讲了，但是，还应该对ebuild_unpack()做类似修改，以便用户可以覆盖缺省解包过程。如果要做任何修补，或者文件包含在多个档案中，则这非常方便。还有个好主意是修改解包代码，以便它可以缺省识别由bzip2 压缩的 tar 压缩包。<br/><br/>配置文件<br/>目前为止，已经讲了很多不方便的 bash技术，现在再讲一个。通常，如果程序在 /etc中有一个配置文件是很方便的。幸运的是，用 bash做到这点很容易。只需创建以下文件，然后并其存为 /etc/ebuild.conf即可：<br/><br/><coolcode>/ect/ebuild.conf</p>
<p># /etc/ebuild.conf: set system-wide ebuild options in this file</p>
<p># MAKEOPTS are options passed to make<br />
MAKEOPTS=&#8221;-j2&#8243;</coolcode><br/><br/>在该例中，只包括了一个配置选项，但是，您可以包括更多。bash的一个妙处是：通过执行该文件，就可以对它进行语法分析。在大多数解释型语言中，都可以使用这个设计窍门。执行/etc/ebuild.conf 之后，在 ebuild 脚本中定义&#8221;$MAKEOPTS&#8221;。将利用它允许用户向 make传递选项。通常，将使用该选项来允许用户告诉 ebuild 执行并行 make。<br/><br/>什么是并行 make？<br/>为了提高多处理器系统的编译速度，make支持并行编译程序。这意味着，make同时编译用户指定数目的源文件（以便使用多处理器系统中的额外处理器），而不是一次只编译一个源文件。通过向make 传递 -j # 选项来启用并行 make，如下所示：<br/><br/><coolcode>make -j4 MAKE=&#8221;make -j4&#8243;</coolcode><br/><br/>这行代码指示 make 同时编译四个程序。MAKE=&#8221;make -j4&#8243;自变量告诉 make，向其启动的任何子 make 进程传递 -j4 选项。<br/><br/>这里是 ebuild 程序的最终版本：<br/><br/>ebuild，最终版本<br/><br/><coolcode>#!/usr/bin/env bash</p>
<p>if [ $# -ne 2 ]<br />
then<br />
    echo &#8220;Please specify ebuild file and unpack, compile or all&#8221;<br />
    exit 1<br />
fi</p>
<p>source /etc/ebuild.conf</p>
<p>if [ -z "$DISTDIR" ]<br />
then<br />
    # set DISTDIR to /usr/src/distfiles if not already set<br />
    DISTDIR=/usr/src/distfiles<br />
fi<br />
export DISTDIR</p>
<p>ebuild_unpack() {<br />
    #make sure we&#039;re in the right directory<br />
    cd ${ORIGDIR}</p>
<p>    if [ -d ${WORKDIR} ]<br />
    then<br />
        rm -rf ${WORKDIR}<br />
    fi</p>
<p>    mkdir ${WORKDIR}<br />
    cd ${WORKDIR}<br />
    if [ ! -e ${DISTDIR}/${A} ]<br />
    then<br />
        echo &#8220;${DISTDIR}/${A} does not exist.  Please download first.&#8221;<br />
        exit 1<br />
    fi<br />
    tar xzf ${DISTDIR}/${A}<br />
    echo &#8220;Unpacked ${DISTDIR}/${A}.&#8221;<br />
    #source is now correctly unpacked<br />
}</p>
<p>user_compile() {<br />
    #we&#039;re already in ${SRCDIR}<br />
    if [ -e configure ]<br />
    then<br />
        #run configure script if it exists<br />
        ./configure &#8211;prefix=/usr<br />
    fi<br />
        #run make<br />
        make $MAKEOPTS MAKE=&#8221;make $MAKEOPTS&#8221;  } </p>
<p>ebuild_compile() {<br />
    if [ ! -d "${SRCDIR}" ]<br />
    then<br />
        echo &#8220;${SRCDIR} does not exist &#8212; please unpack first.&#8221;<br />
        exit 1<br />
    fi<br />
        #make sure we&#039;re in the right directory<br />
    cd ${SRCDIR}<br />
    user_compile<br />
}</p>
<p>export ORIGDIR=&#96;pwd&#96;<br />
export WORKDIR=${ORIGDIR}/work</p>
<p>if [ -e "$1" ]<br />
then<br />
    source $1<br />
else<br />
    echo &#8220;Ebuild file $1 not found.&#8221;<br />
    exit 1<br />
fi</p>
<p>export SRCDIR=${WORKDIR}/${P}</p>
<p>case &#8220;${2}&#8221; in<br />
    unpack)<br />
        ebuild_unpack<br />
        ;;<br />
    compile)<br />
        ebuild_compile<br />
        ;;<br />
    all)<br />
        ebuild_unpack<br />
        ebuild_compile<br />
        ;;<br />
    *)<br />
        echo &#8220;Please specify unpack, compile or all as the second arg&#8221;<br />
        exit 1<br />
        ;;<br />
esac</coolcode><br/><br/>请注意，在文件的开始部分执行/etc/ebuild.conf。另外，还要注意，在缺省 user_compile() 函数中使用&#8221;$MAKEOPTS&#8221;。您可能在想，这管用吗 &#8211; 毕竟，在执行实际上事先定义&#8221;$MAKEOPTS&#8221; 的 /etc/ebuild.conf 之前，我们引用了&#8221;$MAKEOPTS&#8221;。对我们来说幸运的是，这没有问题，因为变量扩展只在执行user_compile() 时才发生。在执行 user_compile() 时，已经执行了/etc/ebuild.conf，并且 &#8220;$MAKEOPTS&#8221; 也被设置成正确的值。</p>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2004/12/10/bash-programming-3.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2004/12/10/bash-programming-3.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bash编程(2)</title>
		<link>http://blog.wgzhao.com/2004/12/10/bash-programming-2.html</link>
		<comments>http://blog.wgzhao.com/2004/12/10/bash-programming-2.html#comments</comments>
		<pubDate>Thu, 09 Dec 2004 17:26:42 +0000</pubDate>
		<dc:creator>wgzhao</dc:creator>
				<category><![CDATA[Linux技术]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=165</guid>
		<description><![CDATA[我们先看一下处理命令行自变量的简单技巧，然后再看看 bash基本编程结构。
 
接收自变量我们使用环境变量 &#8220;$1&#8243;来引用第一个命令行自变量。类似地，可以使用 &#8220;$2&#8243;、&#8221;$3&#8243;等来引用传递给脚本的第二和第三个自变量。这里有一个例子：

 #!/usr/bin/env bash
 echo name of script is $0 echo first argument is $1 echo second argument is $2 echo seventeenth argument is $17 echo number of arguments is $#
除以下两个细节之外，此例无需说明。第一，&#8221;$0&#8243;将扩展成从命令行调用的脚本名称，&#8221;$#&#8221;将扩展成传递给脚本的自变量数目。试验以上脚本，通过传递不同类型的命令行自变量来了解其工作原理。
有时需要一次引用所有命令行自变量。针对这种用途，bash实现了变量 &#8220;$@&#8221;，它扩展成所有用空格分开的命令行参数。在本文稍后的&#8221;for&#8221; 循环部分中，您将看到使用该变量的例子。
 
Bash 编程结构如果您曾用过如 C、Pascal、Python 或 Perl那样的过程语言编程，则一定熟悉 &#8220;if&#8221; 语句和 &#8220;for&#8221;循环那样的标准编程结构。对于这些标准结构的大多数，Bash有自己的版本。在下几节中，将介绍几种 bash结构，并演示这些结构和您已经熟悉的其它编程语言中结构的差异。如果以前编程不多，也不必担心。我提供了足够的信息和示例，使您可以跟上本文的进度。
 
方便的条件语句如果您曾用 C编写过与文件相关的代码，则应该知道：要比较特定文件是否比另一个文件新需要大量工作。那是因为C 没有任何内置语法来进行这种比较，必须使用两个 stat() 调用和两个stat 结构来进行手工比较。相反，bash内置了标准文件比较运算符，因此，确定“/tmp/myfile是否可读”与查看“$myvar 是否大于 4”一样容易。
下表列出最常用的 bash比较运算符。同时还有如何正确使用每一选项的示例。示例要跟在 &#8220;if&#8221;之后。例如：





 [...]]]></description>
			<content:encoded><![CDATA[<p>我们先看一下处理命令行自变量的简单技巧，然后再看看 bash基本编程结构。</p>
<p> <a name="1" id="1"></a>
<p><strong class="subhead">接收自变量</strong><br />我们使用环境变量 &#8220;$1&#8243;来引用第一个命令行自变量。类似地，可以使用 &#8220;$2&#8243;、&#8221;$3&#8243;等来引用传递给脚本的第二和第三个自变量。这里有一个例子：</p>
<p><a name="code1" id="code1"></a></p>
<p> #!/usr/bin/env bash</p>
<p> echo name of script is $0<br /> echo first argument is $1<br /> echo second argument is $2<br /> echo seventeenth argument is $17<br /> echo number of arguments is $#<br/><span id="more-165"></span><br/>
<p>除以下两个细节之外，此例无需说明。第一，&#8221;$0&#8243;将扩展成从命令行调用的脚本名称，&#8221;$#&#8221;将扩展成传递给脚本的自变量数目。试验以上脚本，通过传递不同类型的命令行自变量来了解其工作原理。</p>
<p>有时需要一次引用<i>所有</i>命令行自变量。针对这种用途，bash实现了变量 &#8220;$@&#8221;，它扩展成所有用空格分开的命令行参数。在本文稍后的&#8221;for&#8221; 循环部分中，您将看到使用该变量的例子。</p>
<p> <a name="2" id="2"></a>
<p><strong class="subhead">Bash 编程结构</strong><br />如果您曾用过如 C、Pascal、Python 或 Perl那样的过程语言编程，则一定熟悉 &#8220;if&#8221; 语句和 &#8220;for&#8221;循环那样的标准编程结构。对于这些标准结构的大多数，Bash有自己的版本。在下几节中，将介绍几种 bash结构，并演示这些结构和您已经熟悉的其它编程语言中结构的差异。如果以前编程不多，也不必担心。我提供了足够的信息和示例，使您可以跟上本文的进度。</p>
<p> <a name="3" id="3"></a>
<p><strong class="subhead">方便的条件语句</strong><br />如果您曾用 C编写过与文件相关的代码，则应该知道：要比较特定文件是否比另一个文件新需要大量工作。那是因为C 没有任何内置语法来进行这种比较，必须使用两个 stat() 调用和两个stat 结构来进行手工比较。相反，bash内置了标准文件比较运算符，因此，确定“/tmp/myfile是否可读”与查看“$myvar 是否大于 4”一样容易。</p>
<p>下表列出最常用的 bash比较运算符。同时还有如何正确使用每一选项的示例。示例要跟在 &#8220;if&#8221;之后。例如：</p>
<p><a name="code2" id="code2"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> if [ -z "$myvar" ]then  &nbsp; &nbsp;echo "myvar is not defined"fi</pre>
</td>
</tr>
</tbody>
</table>
<p> <center><br />
<table border="0" bgcolor="#eeeeee">
<tbody>
<tr bgcolor="#0033c0">
<td><b><font color="#ffffff">运算符</font></b></td>
<td><b><font color="#ffffff">描述</font></b></td>
<td><b><font color="#ffffff">示例</font></b></td>
</tr>
<tr bgcolor="#888888">
<td colspan="3"><b><font color="#ffffff">文件比较运算符</font></b></td>
</tr>
<tr>
<td>-e <i>filename</i> </td>
<td>如果 <i>filename</i> 存在，则为真</td>
<td>[ -e /var/log/syslog ]</td>
</tr>
<tr>
<td>-d <i>filename</i> </td>
<td>如果 <i>filename</i> 为目录，则为真</td>
<td>[ -d /tmp/mydir ]</td>
</tr>
<tr>
<td>-f <i>filename</i> </td>
<td>如果 <i>filename</i> 为常规文件，则为真</td>
<td>[ -f /usr/bin/grep ]</td>
</tr>
<tr>
<td>-L <i>filename</i> </td>
<td>如果 <i>filename</i> 为符号链接，则为真</td>
<td>[ -L /usr/bin/grep ]</td>
</tr>
<tr>
<td>-r <i>filename</i> </td>
<td>如果 <i>filename</i> 可读，则为真</td>
<td>[ -r /var/log/syslog ]</td>
</tr>
<tr>
<td>-w <i>filename</i> </td>
<td>如果 <i>filename</i> 可写，则为真</td>
<td>[ -w /var/mytmp.txt ]</td>
</tr>
<tr>
<td>-x <i>filename</i> </td>
<td>如果 <i>filename</i> 可执行，则为真</td>
<td>[ -L /usr/bin/grep ]</td>
</tr>
<tr>
<td><i>filename1</i> -nt <i>filename2</i> </td>
<td>如果 <i>filename1</i> 比 <i>filename2</i> 新，则为真</td>
<td>[ /tmp/install/etc/services -nt /etc/services ]</td>
</tr>
<tr>
<td><i>filename1</i> -ot <i>filename2</i> </td>
<td>如果 <i>filename1</i> 比 <i>filename2</i> 旧，则为真</td>
<td>[ /boot/bzImage -ot arch/i386/boot/bzImage ]</td>
</tr>
<tr bgcolor="#888888">
<td colspan="3"><b><font color="#ffffff">字符串比较运算符</font></b> <font size="-1" color="#ffffff">（请注意引号的使用，这是防止空格扰乱代码的好方法）</font></td>
</tr>
<tr>
<td>-z <i>string</i> </td>
<td>如果 <i>string</i> 长度为零，则为真</td>
<td>[ -z "$myvar" ]</td>
</tr>
<tr>
<td>-n <i>string</i> </td>
<td>如果 <i>string</i> 长度非零，则为真</td>
<td>[ -n "$myvar" ]</td>
</tr>
<tr>
<td><i>string1</i> = <i>string2</i></td>
<td>如果 <i>string1</i> 与 <i>string2</i> 相同，则为真</td>
<td>[ "$myvar" = "one two three" ]</td>
</tr>
<tr>
<td><i>string1</i> != <i>string2</i></td>
<td>如果 <i>string1</i> 与 <i>string2</i> 不同，则为真</td>
<td>[ "$myvar" != "one two three" ]</td>
</tr>
<tr bgcolor="#888888">
<td colspan="3"><b><font color="#ffffff">算术比较运算符</font></b></td>
</tr>
<tr>
<td><i>num1</i> -eq <i>num2</i></td>
<td>等于</td>
<td>[ 3 -eq $mynum ]</td>
</tr>
<tr>
<td><i>num1</i> -ne <i>num2</i></td>
<td>不等于</td>
<td>[ 3 -ne $mynum ]</td>
</tr>
<tr>
<td><i>num1</i> -lt <i>num2</i></td>
<td>小于</td>
<td>[ 3 -lt $mynum ]</td>
</tr>
<tr>
<td><i>num1</i> -le <i>num2</i></td>
<td>小于或等于</td>
<td>[ 3 -le $mynum ]</td>
</tr>
<tr>
<td><i>num1</i> -gt <i>num2</i></td>
<td>大于</td>
<td>[ 3 -gt $mynum ]</td>
</tr>
<tr>
<td><i>num1</i> -ge <i>num2</i></td>
<td>大于或等于</td>
<td>[ 3 -ge $mynum ]</td>
</tr>
</tbody>
</table>
<p></center>
<p>有时，有几种不同方法来进行特定比较。例如，以下两个代码段的功能相同：</p>
<p><a name="code3" id="code3"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> if [ "$myvar" -eq 3 ]then  &nbsp; &nbsp; echo "myvar equals 3"fi

 if [ "$myvar" = "3" ]then  &nbsp; &nbsp; echo "myvar equals 3"fi</pre>
</td>
</tr>
</tbody>
</table>
<p>上面两个比较执行相同的功能，但是第一个使用算术比较运算符，而第二个使用字符串比较运算符。</p>
<p> <a name="4" id="4"></a>
<p><strong class="subhead">字符串比较说明</strong><br />大多数时候，虽然可以不使用括起字符串和字符串变量的双引号，但这并不是好主意。为什么呢？因为如果环境变量中恰巧有一个空格或制表键，bash将无法分辨，从而无法正常工作。这里有一个错误的比较示例：</p>
<p><a name="code4" id="code4"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> if [ $myvar = "foo bar oni" ]then  &nbsp; &nbsp; echo "yes"fi</pre>
</td>
</tr>
</tbody>
</table>
<p>在上例中，如果 myvar 等于&#8221;foo&#8221;，则代码将按预想工作，不进行打印。但是，如果 myvar 等于 &#8220;foobar oni&#8221;，则代码将因以下错误失败：</p>
<p><a name="code5" id="code5"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> [: too many arguments</pre>
</td>
</tr>
</tbody>
</table>
<p>在这种情况下，"$myvar"（等于 "foo bar oni"）中的空格迷惑了bash。bash 扩展 "$myvar" 之后，代码如下：</p>
<p><a name="code6" id="code6"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> [ foo bar oni = "foo bar oni" ]</pre>
</td>
</tr>
</tbody>
</table>
<p>因为环境变量没放在双引号中，所以 bash认为方括号中的自变量过多。可以用双引号将字符串自变量括起来消除该问题。请记住，如果养成将所有字符串自变量用双引号括起的习惯，将除去很多类似的编程错误。&#8221;foobar oni&#8221; 比较<i>应该</i>写成：</p>
<p><a name="code7" id="code7"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> if [ "$myvar" = "foo bar oni" ]then  &nbsp; &nbsp; echo "yes"fi</pre>
</td>
</tr>
</tbody>
</table>
<p>以上代码将按预想工作，而不会有任何令人不快的意外出现。 <a name="5" id="5"></a>
<p><strong class="subhead">循环结构：&#8221;for&#8221;</strong><br />好了，已经讲了条件语句，下面该探索 bash 循环结构了。我们将从标准的&#8221;for&#8221; 循环开始。这里有一个简单的例子：</p>
<p><a name="code8" id="code8"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> #!/usr/bin/env bash

 for x in one two three four do &nbsp; &nbsp; echo number $x done

 <font color="#ff0000">输出：</font>

 number one number two  number three  number four</pre>
</td>
</tr>
</tbody>
</table>
<p>发生了什么？&#8221;for&#8221; 循环中的 &#8220;for x&#8221; 部分定义了一个名为 &#8220;$x&#8221;的新环境变量（也称为循环控制变量），它的值被依次设置为&#8221;one&#8221;、&#8221;two&#8221;、&#8221;three&#8221; 和&#8221;four&#8221;。每一次赋值之后，执行一次循环体（&#8221;do&#8221; 和 &#8220;done&#8221;之间的代码）。在循环体内，象其它环境变量一样，使用标准的变量扩展语法来引用循环控制变量&#8221;$x&#8221;。还要注意，&#8221;for&#8221; 循环总是接收 &#8220;in&#8221;语句之后的某种类型的字列表。在本例中，指定了四个英语单词，但是字列表也可以引用磁盘上的文件，甚至文件通配符。看看下面的例子，该例演示如何使用标准shell 通配符：</p>
<p><a name="code9" id="code9"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> #!/usr/bin/env bash

 for myfile in /etc/r* do &nbsp; &nbsp; if [ -d "$myfile" ] then  &nbsp; &nbsp; &nbsp; echo "$myfile (dir)"else &nbsp; &nbsp; &nbsp; echo "$myfile"fi done

 <font color="#ff0000">输出：</font>

 /etc/rc.d (dir) /etc/resolv.conf /etc/resolv.conf~ /etc/rpc &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</pre>
</td>
</tr>
</tbody>
</table>
<p>以上代码列出在 /etc 中每个以 &#8220;r&#8221; 开头的文件。要做到这点，bash在执行循环之前首先取得通配符 /etc/r*，然后扩展它，用字符串/etc/rc.d /etc/resolv.conf /etc/resolv.conf~ /etc/rpc替换。一旦进入循环，根据 myfile 是否为目录，&#8221;-d&#8221;条件运算符用来执行两个不同操作。如果是目录，则将 &#8220;(dir)&#8221;附加到输出行。</p>
<p>还可以在字列表中使用多个通配符、甚至是环境变量：</p>
<p><a name="code10" id="code10"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> for x in /etc/r??? /var/lo* /home/drobbins/mystuff/* /tmp/${MYPATH}/* do &nbsp; &nbsp; cp $x /mnt/mydir done</pre>
</td>
</tr>
</tbody>
</table>
<p>Bash将在所有正确位置上执行通配符和环境变量扩展，并可能创建一个非常长的字列表。</p>
<p>虽然所有通配符扩展示例使用了<i>绝对</i>路径，但也可以使用相对路径，如下所示：</p>
<p><a name="code11" id="code11"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> for x in ../* mystuff/* do &nbsp; &nbsp; echo $x is a silly file done</pre>
</td>
</tr>
</tbody>
</table>
<p>在上例中，bash相对于当前工作目录执行通配符扩展，就象在命令行中使用相对路径一样。研究一下通配符扩展。您将注意到，如果在通配符中使用绝对路径，bash将通配符扩展成一个绝对路径列表。否则，bash将在后面的字列表中使用相对路径。如果只引用当前工作目录中的文件（例如，如果输入&#8221;for x in*&#8221;），则产生的文件列表将没有路径信息的前缀。请记住，可以使用&#8221;basename&#8221; 可执行程序来除去前面的路径信息，如下所示：</p>
<p><a name="code12" id="code12"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> for x in /var/log/* do &nbsp; &nbsp; echo &#96;basename $x&#96; is a file living in /var/log done</pre>
</td>
</tr>
</tbody>
</table>
<p>当然，在脚本的命令行自变量上执行循环通常很方便。这里有一个如何使用本文开始提到的&#8221;$@&#8221; 变量的例子：</p>
<p><a name="code13" id="code13"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> #!/usr/bin/env bash

 for thing in "$@" do &nbsp; &nbsp; echo you typed ${thing}. done

 <font color="#ff0000">输出：</font>

 $ allargs hello there you silly you typed hello. you typed there. you typed you. you typed silly.</pre>
</td>
</tr>
</tbody>
</table>
<p> <a name="arith" id="arith"></a>
<p><strong class="subhead">Shell 算术</strong><br />在学习另一类型的循环结构之前，最好先熟悉如何执行 shell算术。是的，确实如此：可以使用 shell结构来执行简单的整数运算。只需将特定的算术表达式用 &#8220;$((&#8221; 和 &#8220;))&#8221;括起，bash 就可以计算表达式。这里有一些例子：</p>
<p><a name="newcode1" id="newcode1"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> $ echo $(( 100 / 3 )) 33 $ myvar="56" $ echo $(( $myvar + 12 )) 68 $ echo $(( $myvar - $myvar ))0 $ myvar=$(( $myvar + 1 ))$ echo $myvar 57</pre>
</td>
</tr>
</tbody>
</table>
<p> 您已经熟悉如何执行数学操作，现在该介绍其它两种 bash 循环结构&#8221;while&#8221; 和 &#8220;until&#8221; 了。 <a name="more" id="more"></a>
<p><strong class="subhead">更多的循环结构：&#8221;while&#8221; 和&#8221;until&#8221;</strong><br />只要特定条件为真，&#8221;while&#8221; 语句就会执行，其格式如下：</p>
<p><a name="newcode2" id="newcode2"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> while [ condition ] do &nbsp; &nbsp; statements done</pre>
</td>
</tr>
</tbody>
</table>
<p> 通常使用 &#8220;While&#8221; 语句来循环一定次数，比如，下例将循环 10次：</p>
<p><a name="newcode3" id="newcode3"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> myvar=0 while [ $myvar -ne 10 ] do &nbsp; &nbsp; echo $myvar &nbsp; &nbsp; myvar=$(( $myvar + 1 )) done</pre>
</td>
</tr>
</tbody>
</table>
<p>可以看到，上例使用了算术表达式来使条件最终为假，并导致循环终止。</p>
<p>&#8220;Until&#8221; 语句提供了与 &#8220;while&#8221;语句相反的功能：只要特定条件为<i>假</i>，它们就重复。下面是一个与前面的&#8221;while&#8221; 循环具有同等功能的 &#8220;until&#8221; 循环：</p>
<p><a name="newcode4" id="newcode4"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> myvar=0 until [ $myvar -eq 10 ] do &nbsp; &nbsp; echo $myvar &nbsp; &nbsp; myvar=$(( $myvar + 1 )) done</pre>
</td>
</tr>
</tbody>
</table>
<p> <a name="case" id="case"></a>
<p><strong class="subhead">Case 语句</strong><br />Case 语句是另一种便利的条件结构。这里有一个示例片段：</p>
<p><a name="code14" id="code14"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> case "${x##*.}" in &nbsp; &nbsp; &nbsp;gz) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gzunpack ${SROOT}/${x} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;; &nbsp; &nbsp; &nbsp;bz2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bz2unpack ${SROOT}/${x} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;; &nbsp; &nbsp; &nbsp;*) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;echo "Archive format not recognized." &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;; esac &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</pre>
</td>
</tr>
</tbody>
</table>
<p>在上例中，bash 首先扩展 &#8220;${x##*.}&#8221;。在代码中，&#8221;$x&#8221;是文件的名称，&#8221;${x##.*}&#8221;除去文件中最后句点后文本之外的所有文本。然后，bash 将产生的字符串与&#8221;)&#8221; 左边列出的值做比较。在本例中，&#8221;${x##.*}&#8221; 先与 &#8220;gz&#8221; 比较，然后是&#8221;bz2&#8243;，最后是 &#8220;*&#8221;。如果 &#8220;${x##.*}&#8221;与这些字符串或模式中的任何一个匹配，则执行紧接 &#8220;)&#8221; 之后的行，直到&#8221;;;&#8221; 为止，然后 bash 继续执行结束符 &#8220;esac&#8221;之后的行。如果不匹配任何模式或字符串，则不执行任何代码行，在这个特殊的代码片段中，至少要执行一个代码块，因为任何不与&#8221;gz&#8221; 或 &#8220;bz2&#8243; 匹配的字符串都将与 &#8220;*&#8221; 模式匹配。</p>
<p> <a name="6" id="6"></a>
<p><strong class="subhead">函数与名称空间</strong><br />在 bash 中，甚至可以定义与其它过程语言（如 Pascal 和C）类似的函数。在 bash中，函数甚至可以使用与脚本接收命令行自变量类似的方式来接收自变量。让我们看一下样本函数定义，然后再从那里继续：</p>
<p><a name="code15" id="code15"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> tarview() { &nbsp; &nbsp; echo -n "Displaying contents of $1 " &nbsp; &nbsp; if [ ${1##*.} = tar ]then  &nbsp; &nbsp; &nbsp; &nbsp; echo "(uncompressed tar)" &nbsp; &nbsp; &nbsp; &nbsp; tar tvf $1 &nbsp; &nbsp; elif [ ${1##*.} = gz ]then  &nbsp; &nbsp; &nbsp; &nbsp; echo "(gzip-compressed tar)" &nbsp; &nbsp; &nbsp; &nbsp; tar tzvf $1 &nbsp; &nbsp; elif [ ${1##*.} = bz2 ]then  &nbsp; &nbsp; &nbsp; &nbsp; echo "(bzip2-compressed tar)" &nbsp; &nbsp; &nbsp; &nbsp; cat $1 &#124; bzip2 -d &#124; tar tvf -fi }</pre>
</td>
</tr>
</tbody>
</table>
<p> 
<p>我们在上面定义了一个名为 &#8220;tarview&#8221;的函数，它接收一个自变量，即某种类型的 tar文件。在执行该函数时，它确定自变量是哪种 tar文件类型（未压缩的、gzip 压缩的或 bzip2压缩的），打印一行信息性消息，然后显示 tar文件的内容。应该如下调用上面的函数（在输入、粘贴或找到该函数后，从脚本或命令行调用它）：</p>
<p><a name="code16" id="code16"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> $ tarview shorten.tar.gz Displaying contents of shorten.tar.gz (gzip-compressed tar) drwxr-xr-x ajr/abbot &nbsp; &nbsp; &nbsp; &nbsp; 0 1999-02-27 16:17 shorten-2.3a/ -rw-r--r-- ajr/abbot &nbsp; &nbsp; &nbsp;1143 1997-09-04 04:06 shorten-2.3a/Makefile -rw-r--r-- ajr/abbot &nbsp; &nbsp; &nbsp;1199 1996-02-04 12:24 shorten-2.3a/INSTALL -rw-r--r-- ajr/abbot &nbsp; &nbsp; &nbsp; 839 1996-05-29 00:19 shorten-2.3a/LICENSE .... &nbsp;</pre>
</td>
</tr>
</tbody>
</table>
<p> 
<p>如您所见，可以使用与引用命令行自变量同样的机制来在函数定义内部引用自变量。另外，将把&#8221;$#&#8221; 宏扩展成包含自变量的数目。唯一可能不完全相同的是变量&#8221;$0&#8243;，它将扩展成字符串 &#8220;bash&#8221;（如果从 shell交互运行函数）或调用函数的脚本名称。</p>
<p> <a name="7" id="7"></a>
<p><strong class="subhead">名称空间</strong><br />经常需要在函数中创建环境变量。虽然有可能，但是还有一个技术细节应该了解。在大多数编译语言（如C）中，当在函数内部创建变量时，变量被放置在单独的局部名称空间中。因此，如果在C 中定义一个名为 myfunction 的函数，并在该函数中定义一个名为 &#8220;x&#8221;的自变量，则任何名为 &#8220;x&#8221;的全局变量（函数之外的变量）将不受它的印象，从而消除了负作用。</p>
<p>在 C 中是这样，但在 bash 中却不是。在 bash中，每当在函数内部创建环境变量，就将其添加到<i>全局</i>名称空间。这意味着，该变量将重写函数之外的全局变量，并在函数退出之后继续存在：</p>
<p><a name="code17" id="code17"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> #!/usr/bin/env bash

 myvar="hello"

 myfunc() {

 &nbsp; &nbsp; myvar="one two three" &nbsp; &nbsp; for x in $myvar &nbsp; &nbsp; do &nbsp; &nbsp; &nbsp; &nbsp; echo $x &nbsp; &nbsp; done }

 myfunc

 echo $myvar $x</pre>
</td>
</tr>
</tbody>
</table>
<p>运行此脚本时，它将输出 &#8220;one two threethree&#8221;，这显示了在函数中定义的 &#8220;$myvar&#8221; 如何影响全局变量&#8221;$myvar&#8221;，以及循环控制变量 &#8220;$x&#8221; 如何在函数退出之后继续存在（如果&#8221;$x&#8221; 全局变量存在，也将受到影响）。</p>
<p>在这个简单的例子中，很容易找到该错误，并通过使用其它变量名来改正错误。但这不是正确的方法，解决此问题的最好方法是通过使用&#8221;local&#8221; 命令，在一开始就预防影响全局变量的可能性。当使用 &#8220;local&#8221;在函数内部创建变量时，将把它们放在<i>局部</i>名称空间中，并且不会影响任何全局变量。这里演示了如何实现上述代码，以便不重写全局变量：</p>
<p><a name="code18" id="code18"></a></p>
<table width="100%" cellpadding="0" border="0" class="code-sample">
<tbody>
<tr>
<td>
<pre> #!/usr/bin/env bash

 myvar="hello"

 myfunc() { &nbsp; &nbsp; local x &nbsp; &nbsp; local myvar="one two three" &nbsp; &nbsp; for x in $myvar &nbsp; &nbsp; do &nbsp; &nbsp; &nbsp; &nbsp; echo $x &nbsp; &nbsp; done }

 myfunc

 echo $myvar $x</pre>
</td>
</tr>
</tbody>
</table>
<p> 此函数将输出 &#8220;hello&#8221; &#8212; 不重写全局变量 &#8220;$myvar&#8221;，&#8221;$x&#8221; 在 myfunc之外不继续存在。在函数的第一行，我们创建了以后要使用的局部变量x，而在第二个例子 (local myvar=&#8221;one two three&#8221;")中，我们创建了局部变量myvar，<i>同时</i>为其赋值。在将循环控制变量定义为局部变量时，使用第一种形式很方便，因为不允许说：&#8221;forlocal x in$myvar&#8221;。此函数不影响任何全局变量，鼓励您用这种方式设计所有的函数。只有在明确希望要修改全局变量时，才<i>不</i></p>
<div style="float:left;margin:0px 0px 0px 0px;"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="http://blog.wgzhao.com/2004/12/10/bash-programming-2.html"></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://blog.wgzhao.com/2004/12/10/bash-programming-2.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
