﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客- 攀升·Uranus</title><link>http://www.cppblog.com/iuranus/</link><description>&lt;br&gt;&lt;font color="#ADFF2F"&gt;Something Different，Something New&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Sun, 21 Mar 2010 08:51:52 GMT</lastBuildDate><pubDate>Sun, 21 Mar 2010 08:51:52 GMT</pubDate><ttl>60</ttl><item><title>(转)Bash 实例，第 2 部分</title><link>http://www.cppblog.com/iuranus/archive/2010/03/15/109723.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 15 Mar 2010 03:29:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2010/03/15/109723.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/109723.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2010/03/15/109723.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/109723.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/109723.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="35" sizcache="2">
    <tbody sizset="35" sizcache="1">
        <tr vAlign=top>
            <td width="100%">
            <h1>&nbsp;</h1>
            <h1>转载：<a href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/"><em style="COLOR: #000000">http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/</em></a></h1>
            <h1>&nbsp;</h1>
            <h1>Bash 实例，第 2 部分</h1>
            <p id=subtitle>更多的 bash 基本编程</p>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td>
            <td class=no-print width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="36" sizcache="2">
    <tbody sizset="37" sizcache="2">
        <tr vAlign=top sizset="37" sizcache="2">
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td width="100%" sizset="37" sizcache="2">
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#author"><u><font color=#996699>Daniel Robbins</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#100;&#114;&#111;&#98;&#98;&#105;&#110;&#115;&#64;&#103;&#101;&#110;&#116;&#111;&#111;&#46;&#111;&#114;&#103;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#66;&#97;&#115;&#104;&#32;&#23454;&#20363;&#65292;&#31532;&#32;&#50;&#32;&#37096;&#20998;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#100;&#114;&#111;&#98;&#98;&#105;&#110;&#115;&#64;&#103;&#101;&#110;&#116;&#111;&#111;&#46;&#111;&#114;&#103;"><u><font color=#5c81a7>drobbins@gentoo.org</font></u></a>), 总裁兼 CEO, Gentoo Technologies, Inc.<br></p>
            <p>2000 年 4 月 01 日</p>
            <blockquote>在前一篇 bash 的介绍性文章中，Daniel Robbins 为您讲解了脚本语言的一些基本元素和使用 bash 的原因。在本文（即第二部分）中，Daniel 继续前一篇的内容，并讲解条件 (if-then) 语句、循环和更多的 bash 基本结构。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p>我们先看一下处理命令行自变量的简单技巧，然后再看看 bash 基本编程结构。</p>
            <p><a name=N10051><span class=atitle>接收自变量</span></a></p>
            <p>在 <a href="http://www.ibm.com/software/developerworks/library/bash.html"><u><font color=#5c81a7>介绍性文章</font></u></a> 中的样本程序中，我们使用环境变量 "$1" 来引用第一个命令行自变量。类似地，可以使用 "$2"、"$3" 等来引用传递给脚本的第二和第三个自变量。这里有一个例子： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="42" sizcache="2">
                <tbody sizset="42" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> #!/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 $#
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>除以下两个细节之外，此例无需说明。第一，"$0" 将扩展成从命令行调用的脚本名称，"$#" 将扩展成传递给脚本的自变量数目。试验以上脚本，通过传递不同类型的命令行自变量来了解其工作原理。</p>
            <p>有时需要一次引用 <em>所有</em> 命令行自变量。针对这种用途，bash 实现了变量 "$@"，它扩展成所有用空格分开的命令行参数。在本文稍后的 "for" 循环部分中，您将看到使用该变量的例子。 </p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="43" sizcache="2">
                <tbody sizset="43" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="44" sizcache="2">
                <tbody sizset="45" sizcache="2">
                    <tr align=right sizset="45" sizcache="2">
                        <td sizset="45" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="45" sizcache="2">
                            <tbody sizset="45" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N1006B><span class=atitle>Bash 编程结构</span></a></p>
            <p>如果您曾用过如 C、Pascal、Python 或 Perl 那样的过程语言编程，则一定熟悉 "if" 语句和 "for" 循环那样的标准编程结构。对于这些标准结构的大多数，Bash 有自己的版本。在下几节中，将介绍几种 bash 结构，并演示这些结构和您已经熟悉的其它编程语言中结构的差异。如果以前编程不多，也不必担心。我提供了足够的信息和示例，使您可以跟上本文的进度。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="46" sizcache="2">
                <tbody sizset="46" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="47" sizcache="2">
                <tbody sizset="48" sizcache="2">
                    <tr align=right sizset="48" sizcache="2">
                        <td sizset="48" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="48" sizcache="2">
                            <tbody sizset="48" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10074><span class=atitle>方便的条件语句</span></a></p>
            <p>如果您曾用 C 编写过与文件相关的代码，则应该知道：要比较特定文件是否比另一个文件新需要大量工作。那是因为 C 没有任何内置语法来进行这种比较，必须使用两个 stat() 调用和两个 stat 结构来进行手工比较。相反，bash 内置了标准文件比较运算符，因此，确定&#8220;/tmp/myfile 是否可读&#8221;与查看&#8220;$myvar 是否大于 4&#8221;一样容易。</p>
            <p>下表列出最常用的 bash 比较运算符。同时还有如何正确使用每一选项的示例。示例要跟在 "if" 之后。例如：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="49" sizcache="2">
                <tbody sizset="49" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> if [ -z "$myvar" ]
                        then
                        echo "myvar is not defined"
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p sizset="50" sizcache="2">
            <table cellSpacing=0 cellPadding=3 border=0 sizset="50" sizcache="2">
                <tbody sizset="50" sizcache="1">
                    <tr vAlign=top bgColor=#0033cc>
                        <td><strong>运算符</strong> </td>
                        <td><strong>描述</strong> </td>
                        <td><strong>示例</strong> </td>
                    </tr>
                    <tr vAlign=top bgColor=#888888>
                        <td colSpan=3><strong>文件比较运算符 </strong></td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-e <em>filename</em> </td>
                        <td>如果 <em>filename</em>存在，则为真 </td>
                        <td>[ -e /var/log/syslog ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-d <em>filename</em> </td>
                        <td>如果 <em>filename</em>为目录，则为真 </td>
                        <td>[ -d /tmp/mydir ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-f <em>filename</em> </td>
                        <td>如果 <em>filename</em>为常规文件，则为真 </td>
                        <td>[ -f /usr/bin/grep ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-L <em>filename</em> </td>
                        <td>如果 <em>filename</em>为符号链接，则为真 </td>
                        <td>[ -L /usr/bin/grep ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-r <em>filename</em> </td>
                        <td>如果 <em>filename</em>可读，则为真 </td>
                        <td>[ -r /var/log/syslog ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-w <em>filename</em> </td>
                        <td>如果 <em>filename</em>可写，则为真 </td>
                        <td>[ -w /var/mytmp.txt ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-x <em>filename</em> </td>
                        <td>如果 <em>filename</em>可执行，则为真 </td>
                        <td>[ -L /usr/bin/grep ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>filename1</em>-nt <em>filename2</em> </td>
                        <td>如果 <em>filename1</em>比 <em>filename2</em>新，则为真 </td>
                        <td>[ /tmp/install/etc/services -nt /etc/services ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>filename1</em>-ot <em>filename2</em> </td>
                        <td>如果 <em>filename1</em>比 <em>filename2</em>旧，则为真 </td>
                        <td>[ /boot/bzImage -ot arch/i386/boot/bzImage ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#888888>
                        <td colSpan=3><strong>字符串比较运算符 </strong>（请注意引号的使用，这是防止空格扰乱代码的好方法） </td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-z <em>string</em> </td>
                        <td>如果 <em>string</em>长度为零，则为真 </td>
                        <td>[ -z "$myvar" ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td>-n <em>string</em> </td>
                        <td>如果 <em>string</em>长度非零，则为真 </td>
                        <td>[ -n "$myvar" ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>string1</em>= <em>string2</em> </td>
                        <td>如果 <em>string1</em>与 <em>string2</em>相同，则为真 </td>
                        <td>[ "$myvar" = "one two three" ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>string1</em>!= <em>string2</em> </td>
                        <td>如果 <em>string1</em>与 <em>string2</em>不同，则为真 </td>
                        <td>[ "$myvar" != "one two three" ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#888888>
                        <td colSpan=3><strong>算术比较运算符 </strong></td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>num1</em>-eq <em>num2</em> </td>
                        <td>等于</td>
                        <td>[ 3 -eq $mynum ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>num1</em>-ne <em>num2</em> </td>
                        <td>不等于</td>
                        <td>[ 3 -ne $mynum ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>num1</em>-lt <em>num2</em> </td>
                        <td>小于</td>
                        <td>[ 3 -lt $mynum ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>num1</em>-le <em>num2</em> </td>
                        <td>小于或等于</td>
                        <td>[ 3 -le $mynum ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>num1</em>-gt <em>num2</em> </td>
                        <td>大于</td>
                        <td>[ 3 -gt $mynum ]</td>
                    </tr>
                    <tr vAlign=top bgColor=#eeeeee>
                        <td><em>num1</em>-ge <em>num2</em> </td>
                        <td>大于或等于</td>
                        <td>[ 3 -ge $mynum ]</td>
                    </tr>
                </tbody>
            </table>
            <p>有时，有几种不同方法来进行特定比较。例如，以下两个代码段的功能相同：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="73" sizcache="2">
                <tbody sizset="73" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> if [ "$myvar" -eq 3 ]
                        then
                        echo "myvar equals 3"
                        fi
                        if [ "$myvar" = "3" ]
                        then
                        echo "myvar equals 3"
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>上面两个比较执行相同的功能，但是第一个使用算术比较运算符，而第二个使用字符串比较运算符。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="74" sizcache="2">
                <tbody sizset="74" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="75" sizcache="2">
                <tbody sizset="76" sizcache="2">
                    <tr align=right sizset="76" sizcache="2">
                        <td sizset="76" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="76" sizcache="2">
                            <tbody sizset="76" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10271><span class=atitle>字符串比较说明</span></a></p>
            <p>大多数时候，虽然可以不使用括起字符串和字符串变量的双引号，但这并不是好主意。为什么呢？因为如果环境变量中恰巧有一个空格或制表键，bash 将无法分辨，从而无法正常工作。这里有一个错误的比较示例：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="77" sizcache="2">
                <tbody sizset="77" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> if [ $myvar = "foo bar oni" ]
                        then
                        echo "yes"
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在上例中，如果 myvar 等于 "foo"，则代码将按预想工作，不进行打印。但是，如果 myvar 等于 "foo bar oni"，则代码将因以下错误失败：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="78" sizcache="2">
                <tbody sizset="78" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> [: too many arguments
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在这种情况下，"$myvar"（等于 "foo bar oni"）中的空格迷惑了 bash。bash 扩展 "$myvar" 之后，代码如下：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="79" sizcache="2">
                <tbody sizset="79" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> [ foo bar oni = "foo bar oni" ]
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>因为环境变量没放在双引号中，所以 bash 认为方括号中的自变量过多。可以用双引号将字符串自变量括起来消除该问题。请记住，如果养成将所有字符串自变量用双引号括起的习惯，将除去很多类似的编程错误。"foo bar oni" 比较 <em>应该</em>写成： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="80" sizcache="2">
                <tbody sizset="80" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> if [ "$myvar" = "foo bar oni" ]
                        then
                        echo "yes"
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <table cellSpacing=0 cellPadding=0 width="40%" align=right border=0 sizset="81" sizcache="2">
                <tbody sizset="82" sizcache="2">
                    <tr sizset="82" sizcache="2">
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td sizset="82" sizcache="2">
                        <table cellSpacing=0 cellPadding=5 width="100%" border=1 sizset="82" sizcache="2">
                            <tbody sizset="82" sizcache="1">
                                <tr>
                                    <td bgColor=#eeeeee><a name=N10298><strong>更多引用细节</strong></a><br>
                                    <p>如果要扩展环境变量，则必须将它们用 <em>双引号</em>、而不是单引号括起。单引号 <em>禁用</em> 变量（和历史）扩展。 </p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>以上代码将按预想工作，而不会有任何令人不快的意外出现。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="83" sizcache="2">
                <tbody sizset="83" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="84" sizcache="2">
                <tbody sizset="85" sizcache="2">
                    <tr align=right sizset="85" sizcache="2">
                        <td sizset="85" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="85" sizcache="2">
                            <tbody sizset="85" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N102AB><span class=atitle>循环结构："for"</span></a></p>
            <p>好了，已经讲了条件语句，下面该探索 bash 循环结构了。我们将从标准的 "for" 循环开始。这里有一个简单的例子：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="86" sizcache="2">
                <tbody sizset="86" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        #!/usr/bin/env bash
                        for x in one two three four
                        do
                        echo number $x
                        done
                        输出：
                        number one
                        number two
                        number three
                        number four
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>发生了什么？"for" 循环中的 "for x" 部分定义了一个名为 "$x" 的新环境变量（也称为循环控制变量），它的值被依次设置为 "one"、"two"、"three" 和 "four"。每一次赋值之后，执行一次循环体（"do" 和 "done" 之间的代码）。在循环体内，象其它环境变量一样，使用标准的变量扩展语法来引用循环控制变量 "$x"。还要注意，"for" 循环总是接收 "in" 语句之后的某种类型的字列表。在本例中，指定了四个英语单词，但是字列表也可以引用磁盘上的文件，甚至文件通配符。看看下面的例子，该例演示如何使用标准 shell 通配符：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="87" sizcache="2">
                <tbody sizset="87" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> #!/usr/bin/env bash
                        for myfile in /etc/r*
                        do
                        if [ -d "$myfile" ]
                        then
                        echo "$myfile (dir)"
                        else
                        echo "$myfile"
                        fi
                        done
                        输出：
                        /etc/rc.d (dir)
                        /etc/resolv.conf
                        /etc/resolv.conf~
                        /etc/rpc
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>以上代码列出在 /etc 中每个以 "r" 开头的文件。要做到这点，bash 在执行循环之前首先取得通配符 /etc/r*，然后扩展它，用字符串 /etc/rc.d /etc/resolv.conf /etc/resolv.conf~ /etc/rpc 替换。一旦进入循环，根据 myfile 是否为目录，"-d" 条件运算符用来执行两个不同操作。如果是目录，则将 "(dir)" 附加到输出行。</p>
            <p>还可以在字列表中使用多个通配符、甚至是环境变量：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="88" sizcache="2">
                <tbody sizset="88" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        for x in /etc/r--? /var/lo* /home/drobbins/mystuff/* /tmp/${MYPATH}/*
                        do
                        cp $x /mnt/mydir
                        done
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>Bash 将在所有正确位置上执行通配符和环境变量扩展，并可能创建一个非常长的字列表。</p>
            <p>虽然所有通配符扩展示例使用了 <em>绝对</em>路径，但也可以使用相对路径，如下所示： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="89" sizcache="2">
                <tbody sizset="89" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        for x in ../* mystuff/*
                        do
                        echo $x is a silly file
                        done
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在上例中，bash 相对于当前工作目录执行通配符扩展，就象在命令行中使用相对路径一样。研究一下通配符扩展。您将注意到，如果在通配符中使用绝对路径，bash 将通配符扩展成一个绝对路径列表。否则，bash 将在后面的字列表中使用相对路径。如果只引用当前工作目录中的文件（例如，如果输入 "for x in *"），则产生的文件列表将没有路径信息的前缀。请记住，可以使用 "basename" 可执行程序来除去前面的路径信息，如下所示：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="90" sizcache="2">
                <tbody sizset="90" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        for x in /var/log/*
                        do
                        echo `basename $x` is a file living in /var/log
                        done
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>当然，在脚本的命令行自变量上执行循环通常很方便。这里有一个如何使用本文开始提到的 "$@" 变量的例子：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="91" sizcache="2">
                <tbody sizset="91" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        #!/usr/bin/env bash
                        for thing in "$@"
                        do
                        echo you typed ${thing}.
                        done
                        输出：
                        $ allargs hello there you silly
                        you typed hello.
                        you typed there.
                        you typed you.
                        you typed silly.
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="92" sizcache="2">
                <tbody sizset="92" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="93" sizcache="2">
                <tbody sizset="94" sizcache="2">
                    <tr align=right sizset="94" sizcache="2">
                        <td sizset="94" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="94" sizcache="2">
                            <tbody sizset="94" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N102F0><span class=atitle>Shell 算术</span></a></p>
            <p>在学习另一类型的循环结构之前，最好先熟悉如何执行 shell 算术。是的，确实如此：可以使用 shell 结构来执行简单的整数运算。只需将特定的算术表达式用 "$((" 和 "))" 括起，bash 就可以计算表达式。这里有一些例子：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="95" sizcache="2">
                <tbody sizset="95" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> $ 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>
            <br><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="96" sizcache="2">
                <tbody sizset="96" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="97" sizcache="2">
                <tbody sizset="98" sizcache="2">
                    <tr align=right sizset="98" sizcache="2">
                        <td sizset="98" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="98" sizcache="2">
                            <tbody sizset="98" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N102FD><span class=atitle>更多的循环结构："while" 和 "until"</span></a></p>
            <p>只要特定条件为真，"while" 语句就会执行，其格式如下：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="99" sizcache="2">
                <tbody sizset="99" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> while [ condition ]
                        do
                        statements
                        done
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>通常使用 "While" 语句来循环一定次数，比如，下例将循环 10 次：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="100" sizcache="2">
                <tbody sizset="100" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> myvar=0
                        while [ $myvar -ne 10 ]
                        do
                        echo $myvar
                        myvar=$(( $myvar + 1 ))
                        done
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>可以看到，上例使用了算术表达式来使条件最终为假，并导致循环终止。</p>
            <p>"Until" 语句提供了与 "while" 语句相反的功能：只要特定条件为 <em>假</em> ，它们就重复。下面是一个与前面的 "while" 循环具有同等功能的 "until" 循环： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="101" sizcache="2">
                <tbody sizset="101" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> myvar=0
                        until [ $myvar -eq 10 ]
                        do
                        echo $myvar
                        myvar=$(( $myvar + 1 ))
                        done
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="102" sizcache="2">
                <tbody sizset="102" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="103" sizcache="2">
                <tbody sizset="104" sizcache="2">
                    <tr align=right sizset="104" sizcache="2">
                        <td sizset="104" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="104" sizcache="2">
                            <tbody sizset="104" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N1031E><span class=atitle>Case 语句</span></a></p>
            <p>Case 语句是另一种便利的条件结构。这里有一个示例片段：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="105" sizcache="2">
                <tbody sizset="105" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        case "${x##*.}" in
                        gz)
                        gzunpack ${SROOT}/${x}
                        ;;
                        bz2)
                        bz2unpack ${SROOT}/${x}
                        ;;
                        *)
                        echo "Archive format not recognized."
                        exit
                        ;;
                        esac
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在上例中，bash 首先扩展 "${x##*.}"。在代码中，"$x" 是文件的名称，"${x##.*}" 除去文件中最后句点后文本之外的所有文本。然后，bash 将产生的字符串与 ")" 左边列出的值做比较。在本例中，"${x##.*}" 先与 "gz" 比较，然后是 "bz2"，最后是 "*"。如果 "${x##.*}" 与这些字符串或模式中的任何一个匹配，则执行紧接 ")" 之后的行，直到 ";;" 为止，然后 bash 继续执行结束符 "esac" 之后的行。如果不匹配任何模式或字符串，则不执行任何代码行，在这个特殊的代码片段中，至少要执行一个代码块，因为任何不与 "gz" 或 "bz2" 匹配的字符串都将与 "*" 模式匹配。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="106" sizcache="2">
                <tbody sizset="106" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="107" sizcache="2">
                <tbody sizset="108" sizcache="2">
                    <tr align=right sizset="108" sizcache="2">
                        <td sizset="108" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="108" sizcache="2">
                            <tbody sizset="108" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N1032E><span class=atitle>函数与名称空间</span></a></p>
            <p>在 bash 中，甚至可以定义与其它过程语言（如 Pascal 和 C）类似的函数。在 bash 中，函数甚至可以使用与脚本接收命令行自变量类似的方式来接收自变量。让我们看一下样本函数定义，然后再从那里继续：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="109" sizcache="2">
                <tbody sizset="109" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        tarview() {
                        echo -n "Displaying contents of $1 "
                        if [ ${1##*.} = tar ]
                        then
                        echo "(uncompressed tar)"
                        tar tvf $1
                        elif [ ${1##*.} = gz ]
                        then
                        echo "(gzip-compressed tar)"
                        tar tzvf $1
                        elif [ ${1##*.} = bz2 ]
                        then
                        echo "(bzip2-compressed tar)"
                        cat $1 | bzip2 -d | tar tvf -
                        fi
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <table cellSpacing=0 cellPadding=0 width="40%" align=right border=0 sizset="110" sizcache="2">
                <tbody sizset="111" sizcache="2">
                    <tr sizset="111" sizcache="2">
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td sizset="111" sizcache="2">
                        <table cellSpacing=0 cellPadding=5 width="100%" border=1 sizset="111" sizcache="2">
                            <tbody sizset="111" sizcache="1">
                                <tr>
                                    <td bgColor=#eeeeee><a name=N1033D><strong>另一种情况</strong></a><br>
                                    <p>可以使用 "case" 语句来编写上面的代码。您知道如何编写吗？ </p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>我们在上面定义了一个名为 "tarview" 的函数，它接收一个自变量，即某种类型的 tar 文件。在执行该函数时，它确定自变量是哪种 tar 文件类型（未压缩的、gzip 压缩的或 bzip2 压缩的），打印一行信息性消息，然后显示 tar 文件的内容。应该如下调用上面的函数（在输入、粘贴或找到该函数后，从脚本或命令行调用它）：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="112" sizcache="2">
                <tbody sizset="112" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> $ tarview shorten.tar.gz
                        Displaying contents of shorten.tar.gz (gzip-compressed tar)
                        drwxr-xr-x ajr/abbot         0 1999-02-27 16:17 shorten-2.3a/
                        -rw-r--r-- ajr/abbot      1143 1997-09-04 04:06 shorten-2.3a/Makefile
                        -rw-r--r-- ajr/abbot      1199 1996-02-04 12:24 shorten-2.3a/INSTALL
                        -rw-r--r-- ajr/abbot       839 1996-05-29 00:19 shorten-2.3a/LICENSE
                        ....
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <table cellSpacing=0 cellPadding=0 width="40%" align=right border=0 sizset="113" sizcache="2">
                <tbody sizset="114" sizcache="2">
                    <tr sizset="114" sizcache="2">
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td sizset="114" sizcache="2">
                        <table cellSpacing=0 cellPadding=5 width="100%" border=1 sizset="114" sizcache="2">
                            <tbody sizset="114" sizcache="1">
                                <tr>
                                    <td bgColor=#eeeeee><a name=N10350><strong>交互地使用它们</strong></a><br>
                                    <p>别忘了，可以将函数（如上面的函数）放在 ~/.bashrc 或 ~/.bash_profile 中，以便在 bash 中随时使用它们。 </p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>如您所见，可以使用与引用命令行自变量同样的机制来在函数定义内部引用自变量。另外，将把 "$#" 宏扩展成包含自变量的数目。唯一可能不完全相同的是变量 "$0"，它将扩展成字符串 "bash"（如果从 shell 交互运行函数）或调用函数的脚本名称。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="115" sizcache="2">
                <tbody sizset="115" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="116" sizcache="2">
                <tbody sizset="117" sizcache="2">
                    <tr align=right sizset="117" sizcache="2">
                        <td sizset="117" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="117" sizcache="2">
                            <tbody sizset="117" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N1035D><span class=atitle>名称空间</span></a></p>
            <p>经常需要在函数中创建环境变量。虽然有可能，但是还有一个技术细节应该了解。在大多数编译语言（如 C）中，当在函数内部创建变量时，变量被放置在单独的局部名称空间中。因此，如果在 C 中定义一个名为 myfunction 的函数，并在该函数中定义一个名为 "x" 的自变量，则任何名为 "x" 的全局变量（函数之外的变量）将不受它的印象，从而消除了负作用。</p>
            <p>在 C 中是这样，但在 bash 中却不是。在 bash 中，每当在函数内部创建环境变量，就将其添加到 <em>全局</em>名称空间。这意味着，该变量将重写函数之外的全局变量，并在函数退出之后继续存在： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="118" sizcache="2">
                <tbody sizset="118" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode> #!/usr/bin/env bash
                        myvar="hello"
                        myfunc() {
                        myvar="one two three"
                        for x in $myvar
                        do
                        echo $x
                        done
                        }
                        myfunc
                        echo $myvar $x
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>运行此脚本时，它将输出 "one two three three"，这显示了在函数中定义的 "$myvar" 如何影响全局变量 "$myvar"，以及循环控制变量 "$x" 如何在函数退出之后继续存在（如果 "$x" 全局变量存在，也将受到影响）。</p>
            <p>在这个简单的例子中，很容易找到该错误，并通过使用其它变量名来改正错误。但这不是正确的方法，解决此问题的最好方法是通过使用 "local" 命令，在一开始就预防影响全局变量的可能性。当使用 "local" 在函数内部创建变量时，将把它们放在 <em>局部</em>名称空间中，并且不会影响任何全局变量。这里演示了如何实现上述代码，以便不重写全局变量： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="119" sizcache="2">
                <tbody sizset="119" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>
                        #!/usr/bin/env bash
                        myvar="hello"
                        myfunc() {
                        local x
                        local myvar="one two three"
                        for x in $myvar
                        do
                        echo $x
                        done
                        }
                        myfunc
                        echo $myvar $x
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>此函数将输出 "hello" -- 不重写全局变量 "$myvar"，"$x" 在 myfunc 之外不继续存在。在函数的第一行，我们创建了以后要使用的局部变量 x，而在第二个例子 (local myvar="one two three"") 中，我们创建了局部变量 myvar， <em>同时</em> 为其赋值。在将循环控制变量定义为局部变量时，使用第一种形式很方便，因为不允许说："for local x in $myvar"。此函数不影响任何全局变量，鼓励您用这种方式设计所有的函数。只有在明确希望要修改全局变量时，才 <em>不</em>应该使用 "local"。 </p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/iuranus/aggbug/109723.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2010-03-15 11:29 <a href="http://www.cppblog.com/iuranus/archive/2010/03/15/109723.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)Bash 实例，第一部分 </title><link>http://www.cppblog.com/iuranus/archive/2010/03/15/109722.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 15 Mar 2010 03:13:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2010/03/15/109722.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/109722.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2010/03/15/109722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/109722.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/109722.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="33" sizcache="2">
    <tbody sizset="33" sizcache="1">
        <tr vAlign=top>
            <td width="100%">
            <h1>其实我不想转载，但IBM网站实在太慢了</h1>
            <h1>转自：<a href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/"><span style="COLOR: #000000"><em>http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/</em></span></a></h1>
            <h1>Bash 实例，第一部分</h1>
            <p id=subtitle>Bourne again shell (bash) 基本编程</p>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td>
            <td class=no-print width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="34" sizcache="2">
    <tbody sizset="35" sizcache="2">
        <tr vAlign=top sizset="35" sizcache="2">
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td width="100%" sizset="35" sizcache="2">
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#author"><u><font color=#996699>Daniel Robbins</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#100;&#114;&#111;&#98;&#98;&#105;&#110;&#115;&#64;&#103;&#101;&#110;&#116;&#111;&#111;&#46;&#111;&#114;&#103;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#66;&#97;&#115;&#104;&#32;&#23454;&#20363;&#65292;&#31532;&#19968;&#37096;&#20998;&#38;&#97;&#109;&#112;&#59;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#100;&#114;&#111;&#98;&#98;&#105;&#110;&#115;&#64;&#103;&#101;&#110;&#116;&#111;&#111;&#46;&#111;&#114;&#103;"><u><font color=#5c81a7>drobbins@gentoo.org</font></u></a>), 总裁兼 CEO, Gentoo Technologies, Inc.<br></p>
            <p>2000 年 3 月 01 日</p>
            <blockquote>通过学习如何使用 bash 脚本语言编程，将使 Linux 的日常交互更有趣和有生产力，同时还可以利用那些已熟悉和喜爱的标准 UNIX 概念（如管道和重定向）。在此三部分系列中，Daniel Robbins 将以示例指导您如何用 bash 编程。他将讲述非常基本的知识（这使此系列十分适合初学者），并在后续系列中逐步引入更高级特性。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p>您可能要问：为什么要学习 Bash 编程？好，以下是几条令人信服的理由：</p>
            <p><a name=N1004D><span class=atitle>已经在运行它</span></a></p>
            <p>如果查看一下，可能会发现：您现在正在运行 bash。因为 bash 是标准 Linux shell，并用于各种目的，所以，即使更改了缺省 shell，bash 可能 <em>仍</em> 在系统中某处运行。因为 bash 已在运行，以后运行的任何 bash 脚本都天生是有效利用内存的，因为它们与任何已运行的 bash 进程共享内存。如果正在运行的工具可以胜任工作，并且做得很好，为什么还要装入一个 500K 的解释器？ </p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="40" sizcache="2">
                <tbody sizset="40" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="41" sizcache="2">
                <tbody sizset="42" sizcache="2">
                    <tr align=right sizset="42" sizcache="2">
                        <td sizset="42" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="42" sizcache="2">
                            <tbody sizset="42" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10059><span class=atitle>已经在使用它</span></a></p>
            <p>不仅在运行 bash，实际上，您每天还在与 bash 打交道。它总在那里，因此学习如何最大限度使用它是有意义的。这样做将使您的 bash 经验更有趣和有生产力。但是为什么要学习 bash <em>编程</em> ？很简单，因为您已在考虑如何运行命令、CPing 文件以及管道化和重定向输出。为什么不学习一种语言，以便使用和利用那些已熟悉和喜爱的强大省时的概念？命令 shell 开启了 UNIX 系统的潜能，而 bash 正是 <em>这个</em> Linux shell。它是您和机器之间的高级纽带。增长 bash 知识吧，这将自动提高您在 Linux 和 UNIX 中的生产力 -- 就那么简单。 </p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="43" sizcache="2">
                <tbody sizset="43" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="44" sizcache="2">
                <tbody sizset="45" sizcache="2">
                    <tr align=right sizset="45" sizcache="2">
                        <td sizset="45" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="45" sizcache="2">
                            <tbody sizset="45" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10068><span class=atitle>Bash 困惑</span></a></p>
            <p>以错误方式学习 bash 令人十分困惑。许多新手输入 "man bash" 来查看 bash 帮助页，但只得到非常简单和技术方面的 shell 功能性描述。还有人输入 "info bash"（来查看 GNU 信息文档），只能得到重新显示的帮助页，或者（如果幸运）略为友好的信息文档。</p>
            <p>尽管这可能使初学者有些失望，但标准 bash 文档无法满足所有人的要求，它只适合那些已大体熟悉 shell 编程的人。帮助页中确实有很多极好的技术信息，但对初学者的帮助却有限。</p>
            <p>这就是本系列的目的所在。在本系列中，我将讲述如何实际使用 bash 编程概念，以便编写自己的脚本。与技术描述不同，我将以简单的语言为您解释，使您不仅知道事情做什么，还知道应在何时使用。在此三部分系列末尾，您将可以自己编写复杂的 bash 脚本，并可以自如地使用 bash 以及通过阅读（和理解）标准 bash 文档来补充知识。让我们开始吧。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="46" sizcache="2">
                <tbody sizset="46" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="47" sizcache="2">
                <tbody sizset="48" sizcache="2">
                    <tr align=right sizset="48" sizcache="2">
                        <td sizset="48" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="48" sizcache="2">
                            <tbody sizset="48" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10077><span class=atitle>环境变量</span></a></p>
            <p>在 bash 和几乎所有其它 shell 中，用户可以定义环境变量，这些环境变量在以 ASCII 字符串存储。环境变量的最便利之处在于：它们是 UNIX 进程模型的标准部分。这意味着：环境变量不仅由 shell 脚本独用，而且还可以由编译过的标准程序使用。当在 bash 中&#8220;导出&#8221;环境变量时，以后运行的任何程序，不管是不是 shell 脚本，都可以读取设置。一个很好的例子是 vipw 命令，它通常允许 root 用户编辑系统口令文件。通过将 EDITOR 环境变量设置成喜爱的文本编辑器名称，可以配置 vipw，使其使用该编辑器，而不使用 vi，如果习惯于 xemacs 而确实不喜欢 vi，那么这是很便利的。</p>
            <p>在 bash 中定义环境变量的标准方法是：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="49" sizcache="2">
                <tbody sizset="49" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ myvar='This is my environment variable!'
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>以上命令定义了一个名为 "myvar" 的环境变量，并包含字符串 "This is my environment variable!"。以上有几点注意事项：第一，在等号 "=" 的两边没有空格，任何空格将导致错误（试一下看看）。第二个件要注意的事是：虽然在定义一个字时可以省略引号，但是当定义的环境变量值多于一个字时（包含空格或制表键），引号是必须的。</p>
            <table cellSpacing=0 cellPadding=0 width="40%" align=right border=0 sizset="50" sizcache="2">
                <tbody sizset="51" sizcache="2">
                    <tr sizset="51" sizcache="2">
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td sizset="51" sizcache="2">
                        <table cellSpacing=0 cellPadding=5 width="100%" border=1 sizset="51" sizcache="2">
                            <tbody sizset="51" sizcache="1">
                                <tr>
                                    <td bgColor=#eeeeee><a name=sidebar><strong>引用细节</strong></a><br>
                                    <p>有关如何在 bash 中使用引号的非常详尽的信息，请参阅 bash 帮助页面中的&#8220;引用&#8221;一节。特殊字符序列由其它值&#8220;扩展&#8221;（替换）确实使 bash 中字符串的处理变得复杂。本系列将只讲述最常用的引用功能。 </p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>第三，虽然通常可以用双引号来替代单引号，但在上例中，这样做会导致错误。为什么呢？因为使用单引号禁用了称为扩展的 bash 特性，其中，特殊字符和字符系列由值替换。例如，"!" 字符是历史扩展字符，bash 通常将其替换为前面输入的命令。（本系列文章中将不讲述历史扩展，因为它在 bash 编程中不常用。有关历史扩展的详细信息，请参阅 bash 帮助页中的&#8220;历史扩展&#8221;一节。）尽管这个类似于宏的功能很便利，但我们现在只想在环境变量后面加上一个简单的感叹号，而不是宏。</p>
            <p>现在，让我们看一下如何实际使用环境变量。这有一个例子：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="52" sizcache="2">
                <tbody sizset="52" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ echo $myvar
                        This is my environment variable!
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>通过在环境变量的前面加上一个 $，可以使 bash 用 myvar 的值替换它。这在 bash 术语中叫做&#8220;变量扩展&#8221;。但是，这样做将怎样：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="53" sizcache="2">
                <tbody sizset="53" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ echo foo$myvarbar
                        foo
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>我们希望回显 "fooThis is my environment variable!bar"，但却不是这样。错在哪里？简单地说，bash 变量扩展设施陷入了困惑。它无法识别要扩展哪一个变量：$m、$my、$myvar 、$myvarbar 等等。如何更明确清楚地告述 bash 引用哪一个变量？试一下这个：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="54" sizcache="2">
                <tbody sizset="54" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ echo foo${myvar}bar
                        fooThis is my environment variable!bar
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>如您所见，当环境变量没有与周围文本明显分开时，可以用花括号将它括起。虽然 $myvar 可以更快输入，并且在大多数情况下正确工作，但 ${myvar} 却能在几乎所有情况下正确通过语法分析。除此之外，二者相同，将在本系列的余下部分看到变量扩展的两种形式。请记住：当环境变量没有用空白（空格或制表键）与周围文本分开时，请使用更明确的花括号形式。</p>
            <p>回想一下，我们还提到过可以&#8220;导出&#8221;变量。当导出环境变量时，它可以自动地由以后运行的任何脚本或可执行程序环境使用。shell 脚本可以使用 shell 的内置环境变量支持&#8220;到达&#8221;环境变量，而 C 程序可以使用 getenv() 函数调用。这里有一些 C 代码示例，输入并编译它们 -- 它将帮助我们从 C 的角度理解环境变量：</p>
            <br><a name=N100B4><strong>myvar.c -- 样本环境变量 C 程序</strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="55" sizcache="2">
                <tbody sizset="55" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>#include &lt;stdio.h&gt;
                        #include &lt;stdlib.h&gt;
                        int main(void) {
                        char *myenvvar=getenv("EDITOR");
                        printf("The editor environment variable is set to %s\n",myenvvar);
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>将上面的代码保存到文件 myenv.c 中，然后发出以下命令进行编译：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="56" sizcache="2">
                <tbody sizset="56" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ gcc myenv.c -o myenv
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>现在，目录中将有一个可执行程序，它在运行时将打印 EDITOR 环境变量的值（如果有值的话）。这是在我机器上运行时的情况：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="57" sizcache="2">
                <tbody sizset="57" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ ./myenv
                        The editor environment variable is set to (null)
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>啊... 因为没有将 EDITOR 环境变量设置成任何值，所以 C 程序得到一个空字符串。让我们试着将它设置成特定值：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="58" sizcache="2">
                <tbody sizset="58" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ EDITOR=xemacs
                        $ ./myenv
                        The editor environment variable is set to (null)
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>虽然希望 myenv 打印值 "xemacs"，但是因为还没有导出环境变量，所以它却没有很好地工作。这次让它正确工作：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="59" sizcache="2">
                <tbody sizset="59" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ export EDITOR
                        $ ./myenv
                        The editor environment variable is set to xemacs
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>现在，如您亲眼所见：不导出环境变量，另一个进程（在本例中是示例 C 程序）就看不到环境变量。顺便提一句，如果愿意，可以在一行定义并导出环境变量，如下所示：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="60" sizcache="2">
                <tbody sizset="60" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ export EDITOR=xemacs
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>这与两行版本的效果相同。现在该演示如何使用 unset 来除去环境变量：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="61" sizcache="2">
                <tbody sizset="61" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ unset EDITOR
                        $ ./myenv
                        The editor environment variable is set to (null)
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <table cellSpacing=0 cellPadding=0 width="40%" align=right border=0 sizset="62" sizcache="2">
                <tbody sizset="63" sizcache="2">
                    <tr sizset="63" sizcache="2">
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td sizset="63" sizcache="2">
                        <table cellSpacing=0 cellPadding=5 width="100%" border=1 sizset="63" sizcache="2">
                            <tbody sizset="63" sizcache="1">
                                <tr>
                                    <td bgColor=#eeeeee><a name=N100EA><strong>dirname 和 basename</strong></a><br>
                                    <p>请注意：dirname 和 basename 不是磁盘上的文件或目录，它们只是字符串操作命令。 </p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="64" sizcache="2">
                <tbody sizset="64" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="65" sizcache="2">
                <tbody sizset="66" sizcache="2">
                    <tr align=right sizset="66" sizcache="2">
                        <td sizset="66" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="66" sizcache="2">
                            <tbody sizset="66" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N100F4><span class=atitle>截断字符串概述</span></a></p>
            <p>截断字符串是将初始字符串截断成较小的独立块，它是一般 shell 脚本每天执行的任务之一。很多时候，shell 脚本需要采用全限定路径，并找到结束的文件或目录。虽然可以用 bash 编码实现（而且有趣），但标准 basename UNIX 可执行程序可以极好地完成此工作：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="67" sizcache="2">
                <tbody sizset="67" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ basename /usr/local/share/doc/foo/foo.txt
                        foo.txt
                        $ basename /usr/home/drobbins
                        drobbins
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>Basename 是一个截断字符串的极简便工具。它的相关命令 dirname 返回 basename 丢弃的&#8220;另&#8221;一部分路径。</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="68" sizcache="2">
                <tbody sizset="68" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ dirname /usr/local/share/doc/foo/foo.txt
                        /usr/local/share/doc/foo
                        $ dirname /usr/home/drobbins/
                        /usr/home
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="69" sizcache="2">
                <tbody sizset="69" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="70" sizcache="2">
                <tbody sizset="71" sizcache="2">
                    <tr align=right sizset="71" sizcache="2">
                        <td sizset="71" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="71" sizcache="2">
                            <tbody sizset="71" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10108><span class=atitle>命令替换</span></a></p>
            <p>需要知道一个简便操作：如何创建一个包含可执行命令结果的环境变量。这很容易：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="72" sizcache="2">
                <tbody sizset="72" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ MYDIR=`dirname /usr/local/share/doc/foo/foo.txt`
                        $ echo $MYDIR
                        /usr/local/share/doc/foo
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>上面所做的称为&#8220;命令替换&#8221;。此例中有几点需要指出。在第一行，简单地将要执行的命令以 <em>反引号</em> 括起。那不是标准的单引号，而是键盘中通常位于 Tab 键之上的单引号。可以用 bash 备用命令替换语法来做同样的事： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="73" sizcache="2">
                <tbody sizset="73" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ MYDIR=$(dirname /usr/local/share/doc/foo/foo.txt)
                        $ echo $MYDIR
                        /usr/local/share/doc/foo
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>如您所见，bash 提供多种方法来执行完全一样的操作。使用命令替换可以将任何命令或命令管道放在 ` ` 或 $( ) 之间，并将其分配给环境变量。真方便！下面是一个例子，演示如何在命令替换中使用管道：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="74" sizcache="2">
                <tbody sizset="74" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>MYFILES=$(ls /etc | grep pa)
                        bash-2.03$ echo $MYFILES
                        pam.d passwd
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="75" sizcache="2">
                <tbody sizset="75" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="76" sizcache="2">
                <tbody sizset="77" sizcache="2">
                    <tr align=right sizset="77" sizcache="2">
                        <td sizset="77" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="77" sizcache="2">
                            <tbody sizset="77" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10126><span class=atitle>象专业人员那样截断字符串</span></a></p>
            <p>尽管 basename 和 dirname 是很好的工具，但有时可能需要执行更高级的字符串&#8220;截断&#8221;，而不只是标准的路径名操作。当需要更强的说服力时，可以利用 bash 内置的变量扩展功能。已经使用了类似于 ${MYVAR} 的标准类型的变量扩展。但是 bash 自身也可以执行一些便利的字符串截断。看一下这些例子：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="78" sizcache="2">
                <tbody sizset="78" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ MYVAR=foodforthought.jpg
                        $ echo ${MYVAR##*fo}
                        rthought.jpg
                        $ echo ${MYVAR#*fo}
                        odforthought.jpg
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在第一个例子中，输入了 ${MYVAR##*fo}。它的确切含义是什么？基本上，在 ${ } 中输入环境变量名称，两个 ##，然后是通配符 ("*fo")。然后，bash 取得 MYVAR，找到从字符串 "foodforthought.jpg" 开始处开始、且匹配通配符 "*fo" 的 <em>最长</em> 子字符串，然后将其从字符串的开始处截去。刚开始理解时会有些困难，为了感受一下这个特殊的 "##" 选项如何工作，让我们一步步地看看 bash 如何完成这个扩展。首先，它从 "foodforthought.jpg" 的开始处搜索与 "*fo" 通配符匹配的子字符串。以下是检查到的子字符串： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="79" sizcache="2">
                <tbody sizset="79" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>f
                        fo      MATCHES *fo
                        foo
                        food
                        foodf
                        foodfo      MATCHES *fo
                        foodfor
                        foodfort
                        foodforth
                        foodfortho
                        foodforthou
                        foodforthoug
                        foodforthought
                        foodforthought.j
                        foodforthought.jp
                        foodforthought.jpg
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在搜索了匹配的字符串之后，可以看到 bash 找到两个匹配。它选择最长的匹配，从初始字符串的开始处除去，然后返回结果。</p>
            <p>上面所示的第二个变量扩展形式看起来与第一个相同，但是它只使用一个 "#" -- 并且 bash 执行 <em>几乎</em> 同样的过程。它查看与第一个例子相同的子字符串系列，但是 bash 从初始字符串除去 <em>最短</em> 的匹配，然后返回结果。所以，一查到 "fo" 子字符串，它就从字符串中除去 "fo"，然后返回 "odforthought.jpg"。 </p>
            <p>这样说可能会令人十分困惑，下面以一简单方式记住这个功能。当搜索最长匹配时，使用 ##（因为 ## 比 # 长）。当搜索最短匹配时，使用 #。看，不难记吧！等一下，怎样记住应该使用 '#' 字符来从字符串开始部分除去？很简单！注意到了吗：在美国键盘上，shift-4 是 "$"，它是 bash 变量扩展字符。在键盘上，紧靠 "$" 左边的是 "#"。这样，可以看到："#" 位于 "$" 的&#8220;开始处&#8221;，因此（根据我们的记忆法），"#" 从字符串的开始处除去字符。您可能要问：如何从字符串末尾除去字符。如果猜到我们使用美国键盘上紧靠 "$" <em>右边</em> 的字符 ("%)，那就猜对了。这里有一些简单的例子，解释如何截去字符串的末尾部分： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="80" sizcache="2">
                <tbody sizset="80" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ MYFOO="chickensoup.tar.gz"
                        $ echo ${MYFOO%%.*}
                        chickensoup
                        $ echo ${MYFOO%.*}
                        chickensoup.tar
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>正如您所见，除了将匹配通配符从字符串末尾除去之外，% 和 %% 变量扩展选项与 # 和 ## 的工作方式相同。请注意：如果要从末尾除去特定子字符串，不必使用 "*" 字符：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="81" sizcache="2">
                <tbody sizset="81" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>MYFOOD="chickensoup"
                        $ echo ${MYFOOD%%soup}
                        chicken
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在此例中，使用 "%%" 或 "%" 并不重要，因为只能有一个匹配。还要记住：如果忘记了应该使用 "#" 还是 "%"，则看一下键盘上的 3、4 和 5 键，然后猜出来。</p>
            <p>可以根据特定字符偏移和长度，使用另一种形式的变量扩展，来选择特定子字符串。试着在 bash 中输入以下行：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="82" sizcache="2">
                <tbody sizset="82" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ EXCLAIM=cowabunga
                        $ echo ${EXCLAIM:0:3}
                        cow
                        $ echo ${EXCLAIM:3:7}
                        abunga
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>这种形式的字符串截断非常简便，只需用冒号分开来指定起始字符和子字符串长度。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="83" sizcache="2">
                <tbody sizset="83" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="84" sizcache="2">
                <tbody sizset="85" sizcache="2">
                    <tr align=right sizset="85" sizcache="2">
                        <td sizset="85" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="85" sizcache="2">
                            <tbody sizset="85" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10167><span class=atitle>应用字符串截断</span></a></p>
            <p>现在我们已经学习了所有截断字符串的知识，下面写一个简单短小的 shell 脚本。我们的脚本将接受一个文件作为自变量，然后打印：该文件是否是一个 tar 文件。要确定它是否是 tar 文件，将在文件末尾查找模式 ".tar"。如下所示：</p>
            <br><a name=N10170><strong>mytar.sh -- 一个简单的脚本</strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="86" sizcache="2">
                <tbody sizset="86" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>#!/bin/bash
                        if [ "${1##*.}" = "tar" ]
                        then
                        echo This appears to be a tarball.
                        else
                        echo At first glance, this does not appear to be a tarball.
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>要运行此脚本，将它输入到文件 mytar.sh 中，然后输入 "chmod 755 mytar.sh"，生成可执行文件。然后，如下做一下 tar 文件试验：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="87" sizcache="2">
                <tbody sizset="87" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>$ ./mytar.sh thisfile.tar
                        This appears to be a tarball.
                        $ ./mytar.sh thatfile.gz
                        At first glance, this does not appear to be a tarball.
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>好，成功运行，但是不太实用。在使它更实用之前，先看一下上面使用的 "if" 语句。语句中使用了一个布尔表达式。在 bash 中，"=" 比较运算符检查字符串是否相等。在 bash 中，所有布尔表达式都用方括号括起。但是布尔表达式实际上测试什么？让我们看一下左边。根据前面所学的字符串截断知识，"${1##*.}" 将从环境变量 "1" 包含的字符串开始部分除去最长的 "*." 匹配，并返回结果。这将返回文件中最后一个 "." 之后的所有部分。显然，如果文件以 ".tar" 结束，结果将是 "tar"，条件也为真。</p>
            <p>您可能会想：开始处的 "1" 环境变量是什么。很简单 -- $1 是传给脚本的第一个命令行自变量，$2 是第二个，以此类推。好，已经回顾了功能，下面来初探 "if" 语句。</p>
            <br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="88" sizcache="2">
                <tbody sizset="88" sizcache="1">
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right sizset="89" sizcache="2">
                <tbody sizset="90" sizcache="2">
                    <tr align=right sizset="90" sizcache="2">
                        <td sizset="90" sizcache="2"><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0 sizset="90" sizcache="2">
                            <tbody sizset="90" sizcache="1">
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=N10187><span class=atitle>If 语句</span></a></p>
            <p>与大多数语言一样，bash 有自己的条件形式。在使用时，要遵循以上格式；即，将 "if" 和 "then" 放在不同行，并使 "else" 和结束处必需的 "fi" 与它们水平对齐。这将使代码易于阅读和调试。除了 "if,else" 形式之外，还有其它形式的 "if" 语句：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="91" sizcache="2">
                <tbody sizset="91" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>if [ condition ]
                        then
                        action
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>只有当 <code>condition</code> 为真时，该语句才执行操作，否则不执行操作，并继续执行 "fi" 之后的任何行。 </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0 sizset="92" sizcache="2">
                <tbody sizset="92" sizcache="1">
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>if [ condition ]
                        then
                        action
                        elif [ condition2 ]
                        then
                        action2
                        .
                        .
                        .
                        elif [ condition3 ]
                        then
                        else
                        actionx
                        fi
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>以上 "elif" 形式将连续测试每个条件，并执行符合第一个 <em>真</em> 条件的操作。如果没有条件为真，则将执行 "else" 操作，如果有一个条件为真，则继续执行整个 "if,elif,else" 语句之后的行</p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/iuranus/aggbug/109722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2010-03-15 11:13 <a href="http://www.cppblog.com/iuranus/archive/2010/03/15/109722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)C++程序调用C函数</title><link>http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 08 Mar 2010 07:23:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/109187.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/109187.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/109187.html</trackback:ping><description><![CDATA[<p>转自：<a href="http://blog.csdn.net/ustcgy/archive/2009/12/23/5063082.aspx">http://blog.csdn.net/ustcgy/archive/2009/12/23/5063082.aspx</a><br><br>这种需求很多,又因为C++和C是两种完全不同的编译链接处理方式,所以要稍加处理.总结大致有两大类实现方法.</p>
<p>文中给出的是完整的,具体的,但又最基本最简单的实现,至于理论性的东西在网上很容易搜索的到.</p>
<p><strong>一.通过处理被调用的C头文件</strong></p>
<p><span style="COLOR: rgb(0,0,255)">a.h:</span></p>
<p>#ifndef __A_H<br>#define __A_H</p>
<p>#ifdef __cplusplus<br>extern "C" {<br>#endif</p>
<p>int ThisIsTest(int a, int b);</p>
<p>#ifdef __cplusplus<br>}<br>#endif</p>
<p>#endif</p>
<p><span style="COLOR: rgb(0,0,255)">a.c:</span></p>
<p>#include "a.h"</p>
<p>int ThisIsTest(int a, int b) {<br>&nbsp; return (a + b);<br>}</p>
<p><span style="COLOR: rgb(0,0,255)">aa.h:</span></p>
<p>class AA {<br>&nbsp; public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int bar(int a, int b);<br>};</p>
<p><span style="COLOR: rgb(0,0,255)">aa.cpp:</span></p>
<p>#include "a.h"<br>#include "aa.h"<br>#include "stdio.h"</p>
<p>int AA::bar(int a, int b){ <br>&nbsp;&nbsp;&nbsp; printf("result=%d\n", ThisIsTest(a, b)); <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p><span style="COLOR: rgb(0,0,255)">main.cpp:</span></p>
<p>#include "aa.h"</p>
<p>int main(int argc, char **argv){ <br>&nbsp; int a = 1; <br>&nbsp; int b = 2; <br>&nbsp; AA* aa = new AA(); <br>&nbsp; aa-&gt;bar(a, b); <br>&nbsp; delete(aa);<br>&nbsp; return(0); <br>}</p>
<p><span style="COLOR: rgb(0,0,255)">Makefile:</span></p>
<p>all:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc -Wall -c a.c -o a.o<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc -Wall -c aa.cpp -o aa.o<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc -Wall -c main.cpp -o main.o<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g++ -o test *.o</p>
<p><strong>二. 通过处理调用的C++文件</strong></p>
<p>恢复a.h文件为一般性C头文件,在aa.cpp文件中extern包含a.h头文件或函数.</p>
<p><span style="COLOR: rgb(0,0,255)">a.h:</span></p>
<p>#ifndef __A_H<br>#define __A_H<br>int ThisIsTest(int a, int b);<br>#endif</p>
<p><span style="COLOR: rgb(0,0,255)">aa.cpp:</span></p>
<p>extern "C"<br>{<br>&nbsp;&nbsp;&nbsp; #include "a.h"<br>}<br>#include "aa.h"<br>#include "stdio.h"</p>
<p>int AA::bar(int a, int b){ <br>&nbsp;&nbsp;&nbsp; printf("result=%d\n", ThisIsTest(a, b)); <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>or</p>
<p><span style="COLOR: rgb(0,0,255)">aa.cpp:</span></p>
<p>#include "aa.h"<br>#include "stdio.h"</p>
<p>extern "C"<br>{<br>&nbsp;&nbsp;&nbsp; int ThisIsTest(int a, int b);<br>}</p>
<p>int AA::bar(int a, int b){ <br>&nbsp;&nbsp;&nbsp; printf("result=%d\n", ThisIsTest(a, b)); <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/109187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2010-03-08 15:23 <a href="http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）UNIX IO---再谈文件描述符 </title><link>http://www.cppblog.com/iuranus/archive/2009/12/22/103681.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 22 Dec 2009 03:20:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/12/22/103681.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/103681.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/12/22/103681.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/103681.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/103681.html</trackback:ping><description><![CDATA[<div>在C程序中，文件由文件指针或者文件描述符表示。ISO C的标准I/0库函数（fopen, fclose, fread,
fwrite, fscanf, fprintf等）使用文件指针，UNIX的I/O函数（open, close, read, write,
ioctl）使用文件描述符。下面重点来说下，文件描述符是如何工作的。</div>
<div>&nbsp;</div>
<div>文件描述符相当于一个逻辑句柄，而open,close等函数则是将文件或者物理设备与句柄相关联。句柄是一个整数，可以理解为进程特定的文件
描述符表的索引。先介绍下面三个概念，后面讲下open、close等操作以后，文件和文件描述符产生什么关系，以及fork后文件描述符的继承等问题。</div>
<div>&nbsp;</div>
<div><strong> 文件描述符表</strong> ：用户区的一部分，除非通过使用文件描述符的函数，否则程序无法对其进行访问。对进程中每个打开的文件，文件描述符表都包含一个条目。</div>
<div>&nbsp;</div>
<div><strong> 系统文件表</strong> ：为系统中所有的进程共享。对每个活动的open, 它都包含一个条目。每个系统文件表的条目都包含文件偏移量、访问模式（读、写、or 读-写）以及指向它的文件描述符表的条目计数。</div>
<div>&nbsp;</div>
<div><strong> 内存索引节点表:</strong>  对系统中的每个活动的文件（被某个进程打开了），内存中索引节点表都包含一个条目。几个系统文件表条目可能对应于同一个内存索引节点表（不同进程打开同一个文件）。</div>
<div>&nbsp;</div>
<div>1、举例: 执行myfd = open( "/home/lucy/my.dat", O_RDONLY); 以后，上述3个表的关系原理图如下：</div>
<div><img onclick="'window.open("http://blog.51cto.com/viewpic.php?refimg="" + this.src)' alt="http://keren.blog.51cto.com/" src="http://img1.51cto.com/attachment/200906/200906291246256898312.bmp" border="0"></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图1</div>
<div>&nbsp;</div>
<div>系统文件表包含一个偏移量，给出了文件当前的位置。若2个进程同时打开一个文件（如上图A,B）做读操作，每个进程都有自己相对于文件的偏移
量，而且读入整个文件是独立于另一个进程的；如果2个进程打开同一个文件做写操作，写操作是相互独立的，每个进程都可以重写另一个进程写入的内容。</div>
<div>&nbsp;</div>
<div>如果上面进程在open以后又执行了close（）函数，操作系统会删除文件描述符表的第四个条目，和系统文件表的对应条目（若指向它的描述符
表唯一），并对内存索引节点表条目中的计数减1，如果自减以后变为0，说明没有其他进程链接此文件，将索引节点表条目也删除，而这里进程B也在open这
个文件，所以索引节点表条目保留。</div>
<div>&nbsp;</div>
<div>2、文件描述符的继承</div>
<div>通过fork（）创建子进程时，子进程继承父进程环境和上下文的大部分内容的拷贝，其中就包括文件描述符表。</div>
<div>&nbsp;</div>
<div>（1）对于父进程在fork（）之前打开的文件来说，子进程都会继承，与父进程共享相同的文件偏移量。如下图所示（0-1-2 表示 标准输入-输出-错误）：</div>
<div><img onclick="'window.open("http://blog.51cto.com/viewpic.php?refimg="" + this.src)' alt="" src="http://img1.51cto.com/attachment/200906/200906291246258303796.bmp" border="0" width="675" height="447"></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图2 fork()之前打开my.dat</div>
<div>&nbsp;</div>
<div>系统文件表位于系统空间中，不会被fork()复制，但是系统文件表中的条目会保存指向它的文件描述符表的计数，fork()时需要对这个计数
进行维护，以体现子进程对应的新的文件描述符表也指向它。程序关闭文件时，也是将系统文件表条目内部的计数减一，当计数值减为0时，才将其删除。</div>
<div>&nbsp;</div>
<div>（2）相反，如果父进程先进程fork，再打开my.dat，这时父子进程关于my.dat
的文件描述符表指向不同的系统文件表条目，也不再共享文件偏移量（fork以后2个进程分别open，在系统文件表中创建2个条目）；但是关于标准输入，
标准输出，标准错误，父子进程还是共享的。</div>
<div><img onclick="'window.open("http://blog.51cto.com/viewpic.php?refimg="" + this.src)' alt="" src="http://img1.51cto.com/attachment/200906/200906291246259052281.bmp" border="0"></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图3&nbsp;&nbsp; fork()以后打开my.dat</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<p>本文出自 &#8220;<a href="http://keren.blog.51cto.com/">淡泊明志，宁静致远</a>&#8221; 博客，请务必保留此出处<a href="http://keren.blog.51cto.com/720558/170822">http://keren.blog.51cto.com/720558/170822</a></p>
<br><img src ="http://www.cppblog.com/iuranus/aggbug/103681.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-12-22 11:20 <a href="http://www.cppblog.com/iuranus/archive/2009/12/22/103681.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dup与赋值语句用于文件描述符的区别（聚合）</title><link>http://www.cppblog.com/iuranus/archive/2009/12/22/103672.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 22 Dec 2009 02:10:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/12/22/103672.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/103672.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/12/22/103672.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/103672.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/103672.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; dup/dup2的使用请参考其他资料，个人只是想了解dup后文件描述符，进程表项，文件表的关系。<br><br>&nbsp;&nbsp;&nbsp; 进程要对文件进行操作，一般使用open调用打开一个文件进行访问，每个进程都有一个文件描述符表，该表中存放打开的文件描述符。用户使用open等调用得到的文件描述符其实是文件描述符在该表中的索引号，该表项的内容是一个指向文件表的指针。应用程序只要使用该描述符就可以对指定文件进行操作。
<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 为了了解dup与赋值语句用于文件描述符的区别，请看如下程序。
<p>程序描述：</p>
<p>&nbsp;&nbsp;&nbsp; 打开一个文件描述符，分别适用dup和赋值语句进行复制，复制之后，打印原始和被复制的文件描述符id，看看是否具有相同的值，然后关闭文件，测试关闭是否成功。</p>
<p>程序示例：</p>
<p>#include &lt;stdio.h&gt;</p>
<p>#include &lt;stdlib.h&gt;</p>
<p>#include &lt;fcntl.h&gt;</p>
<p>#include &lt;unistd.h&gt;</p>
<p>&nbsp;</p>
<p>int sys_err(char *str)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; puts(str);</p>
<p>&nbsp;&nbsp;&nbsp; exit(0);</p>
<p>}</p>
<p>&nbsp;</p>
<p>int main(void)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp; int p,q;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; if((p=open("c_fid.c", O_RDONLY)) == -1)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sys_err("open error");</p>
<p>&nbsp;&nbsp;&nbsp; q = dup(p);</p>
<p>&nbsp;&nbsp;&nbsp; puts("dup:");</p>
<p>&nbsp;&nbsp;&nbsp; printf("file p,q fd is:%d %d\n", q, p);</p>
<p>&nbsp;&nbsp;&nbsp; printf("close file p ok?: %d\n", close(p));</p>
<p>&nbsp;&nbsp;&nbsp; printf("close file q ok?: %d\n", close(q));</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; if((p=open("c_fid.c", O_RDONLY)) == -1)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sys_err("open error");</p>
<p>&nbsp;&nbsp;&nbsp; q = p;</p>
<p>&nbsp;&nbsp;&nbsp; puts("=:");</p>
<p>&nbsp;&nbsp;&nbsp; printf("file p,q fd is:%d %d\n", q, p);</p>
<p>&nbsp;&nbsp;&nbsp; printf("close file p ok?: %d\n", close(p));</p>
<p>&nbsp;&nbsp;&nbsp; printf("close file q ok?: %d\n", close(q));</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; return 0;</p>
<p>}</p>
<p>&nbsp;</p>
<p>程序运行结果：</p>
<p>dup:</p>
<p>file p,q fd is:4 3&nbsp;&nbsp; //文件p,q使用不同的文件描述符</p>
<p>close file p ok?: 0</p>
<p>close file q ok?: 0 //文件关闭成功</p>
<p>=:</p>
<p>file p,q fd is:3 3 //简单复制</p>
<p>close file p ok?: 0</p>
<p>close file q ok?: -1//关闭失败，原因是此描述符已经被关闭了</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 由此证明，dup是产生一个新的文件描述符id和指针在进程表项中，但是他们共用文件表，这时，关闭一个文件描述符，另外一个仍旧可用，文件表并不会被释放。而赋值语句不同，它只是简单的在另外一个变量中记录原始文件指针等，2个变量的文件描述符相同，进程表项中并不产生新的项目。</p>
<p>关于socket的文件描述符<br></p>
<p>&nbsp;&nbsp;&nbsp; socket接口增加了网络通信操作的抽象定义，与文件操作一样，每个打开的socket都对应一个整数，我们称它为socket描述符，该整数也是socket描述符在文件描述符表中的索引值。但socket描述符在描述符表中的表项并不指向文件表，而是指向一个与该socket有关的数据结构。BSD UNIX中新增加了一个socket调用，应用程序可以调用它来新建一个socket描述符，注意进程用open只能产生文件描述符，而不能产生socket描述符。socket调用只能完成建立通信的部分工作，一旦建立了一个socket，应用程序可以使用其他特定的调用来为它添加其他详细信息，以完成建立通信的过程。
<br></p><img src ="http://www.cppblog.com/iuranus/aggbug/103672.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-12-22 10:10 <a href="http://www.cppblog.com/iuranus/archive/2009/12/22/103672.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>上海3G体验－中国电信</title><link>http://www.cppblog.com/iuranus/archive/2009/08/28/94698.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Fri, 28 Aug 2009 12:48:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/28/94698.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/94698.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/28/94698.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/94698.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/94698.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 去了移动，今天去电信, 电信3G制式是CDMA2000，应该是我期望最大的一种了把。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 电信上海体验店位于赵家浜路1111号美罗城3楼，地铁做到徐家汇<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 进门感觉也很好，主要分两个板块，手机3G展示，电脑3G展示。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 手机：好像只能去专门的一个网站看视频，还比较流畅，感觉不错<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 电脑：也是插3G的卡，速度明显比移动的快多了，看youku没问题。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我大概做了一个测试，结果：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下传：200KBPS/70KBPS<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 长传：100KBPS/40KBPS<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 除了速度我满意以外，资费也比较好，它和家里的电话，IPTV，ADSL，3G（40M）绑定，共199，真的是比较实惠了，想想将来应该更便宜，到时候我宽带和3G绑在一起价钱便宜，不就很划算了。<br><img src ="http://www.cppblog.com/iuranus/aggbug/94698.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-28 20:48 <a href="http://www.cppblog.com/iuranus/archive/2009/08/28/94698.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>上海3G体验－中国移动</title><link>http://www.cppblog.com/iuranus/archive/2009/08/16/93521.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sun, 16 Aug 2009 13:58:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/16/93521.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/93521.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/16/93521.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/93521.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/93521.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2009/08/16/93521.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/93521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-16 21:58 <a href="http://www.cppblog.com/iuranus/archive/2009/08/16/93521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java内部类</title><link>http://www.cppblog.com/iuranus/archive/2009/08/15/93394.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sat, 15 Aug 2009 02:57:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/15/93394.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/93394.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/15/93394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/93394.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/93394.html</trackback:ping><description><![CDATA[<strong><font color=#0000ff>一个内部类对象可以访问创建它的外部类对象的内容</font></strong>，甚至包括私有变量，在创建非静态内部类对象时，一定要先创建起相应的外部类对象。<br><br>静态内部类没有了指向外部的引用。<br><br><br>在任何非静态内部类中，都不能有静态数据，静态方法或者又一个静态内部类（内部类的嵌套可以不止一层）。不过静态内部类中却可以拥有这一切。这也算是两者的第二个区别吧。<br>
<img src ="http://www.cppblog.com/iuranus/aggbug/93394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-15 10:57 <a href="http://www.cppblog.com/iuranus/archive/2009/08/15/93394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转) AIDL --- Android中的远程接口</title><link>http://www.cppblog.com/iuranus/archive/2009/08/12/93040.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Wed, 12 Aug 2009 09:17:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/12/93040.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/93040.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/12/93040.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/93040.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/93040.html</trackback:ping><description><![CDATA[<div class="blog_li" style="padding: 0px; text-align: center; margin-bottom: 10px;">
<strong style="font-size: 16px;">AIDL --- Android中的远程接口<br>http://labs.chinamobile.com/community/my_blog/517/4850<br><br></strong></div>
<strong style="font-size: 16px;">
&nbsp;&nbsp;&nbsp; 在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service.
在不同的进程中, 怎样传递对象呢?&nbsp; 显然, Java中不允许跨进程内存共享. 因此传递对象, 只能把对象拆分成操作系统能理解的简单形式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化传递对象. 在Android中, 则采用AIDL的方式. 理论上AIDL可以传递Bundle,实际上做起来却比较麻烦.
</strong>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码，通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数),
然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象. </strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">AIDL的IPC的机制和COM或CORBA类似, 是基于接口的，但它是轻量级的。它使用代理类在客户端和实现层间传递值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相关类.; 2.
调用aidl产生的class.<a name=".E4.BD.BF.E7.94.A8AIDL.E5.AE.9E.E7.8E.B0"></a>
<p><strong style="font-size: 16px;">具体实现步骤如下: </strong></p>
<p><strong style="font-size: 16px;">1、创建AIDL文件,
在这个文件里面定义接口, 该接口定义了可供客户端访问的方法和属性。 如: ITaskBinder.adil</strong></p>
<p><strong style="font-size: 16px;">package com.cmcc.demo;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">import com.cmcc.demo.ITaskCallback;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">interface ITaskBinder {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
boolean isTaskRunning();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void stopRunningTask();&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void registerCallback(ITaskCallback cb);&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void unregisterCallback(ITaskCallback cb);</strong></p>
<p><strong style="font-size: 16px;">}</strong></p>
<p><strong style="font-size: 16px;">其中: ITaskCallback在文件ITaskCallback.aidl中定义:</strong></p>
<p><strong style="font-size: 16px;">package com.cmcc.demo;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">interface ITaskCallback {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; void
actionPerformed(int actionId);</strong></p>
<p><strong style="font-size: 16px;">}</strong></p>
<p><strong style="font-size: 16px;">注意: 理论上, 参数可以传递基本数据类型和String, 还有就是Bundle的派生类, 不过在Eclipse中,目前的ADT不支持Bundle做为参数, 据说用Ant编译可以, 我没做尝试.</strong></p>
<p><strong style="font-size: 16px;">2、编译AIDL文件,
用Ant的话, 可能需要手动, 使用Eclipse plugin的话,可以根据adil文件自动生产java文件并编译,
不需要人为介入. </strong></p>
<p><strong style="font-size: 16px;">3、在Java文件中,
实现AIDL中定义的接口. 编译器会根据AIDL接口, 产生一个JAVA接口。这个接口有一个名为Stub的内部抽象类，它继承扩展了接口并实现了远程调用需要的几个方法。接下来就需要自己去实现自定义的几个接口了.</strong></p>
<p><strong style="font-size: 16px;">ITaskBinder.aidl中接口的实现, 在MyService.java中接口以内嵌类的方式实现:</strong></p>
<p><strong style="font-size: 16px;"><strong>private</strong> <strong>final</strong> ITaskBinder.Stub mBinder = <strong>new</strong> ITaskBinder.Stub() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> stopRunningTask() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //@TODO</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>boolean</strong> isTaskRunning() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //@TODO</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>return</strong> <strong>false</strong>;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> registerCallback(ITaskCallback cb) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> (cb != <strong>null</strong>) mCallbacks.register(cb);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> unregisterCallback(ITaskCallback cb) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> (cb != <strong>null</strong>) mCallbacks.unregister(cb);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">};</strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">在MyActivity.java中ITaskCallback.aidl接口实现:</strong></p>
<p><strong style="font-size: 16px;"><strong>private</strong> ITaskCallback mCallback = <strong>new</strong> ITaskCallback.Stub() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> actionPerformed(<strong>int</strong> id) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //TODO</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("callback id=" + id);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">};</strong></p>
<p><strong style="font-size: 16px;">4、向客户端提供接口ITaskBinder, 如果写的是service，扩展该Service并重载onBind ()方法来返回一个实现上述接口的类的实例。这个地方返回的mBinder,就是上面通过内嵌了定义的那个. (MyService.java)</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> IBinder onBind(Intent t) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service on bind");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>return</strong> mBinder;</strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">}</strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">在Activity中, 可以通过Binder定义的接口, 来进行远程调用. </strong></p>
<p><strong style="font-size: 16px;"><a name=".E5.88.9B.E5.BB.BA.E4.B8.80.E4.B8.AAAIDL"></a>5、在服务器端回调客户端的函数. 前提是当客户端获取的IBinder接口的时候,要去注册回调函数, 只有这样, 服务器端才知道该调用那些函数在:MyService.java中:</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>void</strong> callback(<strong>int</strong> val) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>final</strong> <strong>int</strong> N = mCallbacks.beginBroadcast();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>for</strong> (<strong>int</strong> i=0; i&lt;N; i++) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>try</strong> {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mCallbacks.getBroadcastItem(i).actionPerformed(val);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <strong>catch</strong> (RemoteException e) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The RemoteCallbackList will take care of removing</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the dead object for us.</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mCallbacks.finishBroadcast();</strong></p>
<p style="text-indent: 21pt;"><strong style="font-size: 16px;">}</strong></p>
<p><strong style="font-size: 16px;">AIDL的创建方法:</strong></p>
<p><strong style="font-size: 16px;">AIDL语法很简单,可以用来声明一个带一个或多个方法的接口，也可以传递参数和返回值。
由于远程调用的需要, 这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型: </strong></p>
<p><strong style="font-size: 16px;">1. 不需要import声明的简单Java编程语言类型(int,boolean等) </strong></p>
<pre><strong style="font-size: 16px;">2. String, CharSequence不需要特殊声明</strong></pre>
<pre><strong style="font-size: 16px;"> </strong></pre>
<pre><strong style="font-size: 16px;">3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型. </strong></pre>
<pre><strong style="font-size: 16px;">(</strong></pre>
<pre><strong style="font-size: 16px;">(另外: 我没尝试Parcelables, 在Eclipse+ADT下编译不过, 或许以后会有所支持).</strong></pre>
<pre><strong style="font-size: 16px;">下面是AIDL语法:</strong></pre>
<pre><strong style="font-size: 16px;"> // 文件名: SomeClass.aidl</strong></pre>
<pre><strong style="font-size: 16px;"> // 文件可以有注释, 跟java的一样</strong></pre>
<pre><strong style="font-size: 16px;"> // 在package以前的注释, 将会被忽略.</strong></pre>
<pre><strong style="font-size: 16px;"> // 函数和变量以前的注释, 都会被加入到生产java代码中.</strong></pre>
<pre><strong style="font-size: 16px;">package com.cmcc.demo;</strong></pre>
<pre><strong style="font-size: 16px;"> // import 引入语句</strong></pre>
<p><strong style="font-size: 16px;">import com.cmcc.demo.ITaskCallback;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">interface ITaskBinder {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; //函数跟java一样, 可以有0到多个参数 ,可以有一个返回值</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
boolean isTaskRunning();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void stopRunningTask();&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; //参数可以是另外的一个aidl定义的接口</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void registerCallback(ITaskCallback cb);&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">void
unregisterCallback(ITaskCallback cb);</strong></p>
<p><strong style="font-size: 16px;">//参数可以是String, 可以用in表入输入类型, out表示输出类型.</strong></p>
<pre style="text-indent: 18pt;"><strong style="font-size: 16px;">int getCustomerList(in String branch, out String[] customerList);</strong></pre>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<pre><strong style="font-size: 16px;">} </strong></pre>
<p><strong style="font-size: 16px;"><a name=".E5.AE.9E.E7.8E.B0.E6.8E.A5.E5.8F.A3"></a>实现接口时有几个原则:
</strong></p>
<pre><strong style="font-size: 16px;">.抛出的异常不要返回给调用者. 跨进程抛异常处理是不可取的.</strong></pre>
<pre><strong style="font-size: 16px;">.IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话，你应该避免在Activity的主线程中调用。 也就是IPC调用会挂起应用程序导致界面失去响应. 这种情况应该考虑单起一个线程来处理.</strong></pre>
<pre><strong style="font-size: 16px;">.不能在AIDL接口中声明静态属性。</strong></pre>
<p><strong style="font-size: 16px;"><a name=".E5.90.91.E5.AE.A2.E6.88.B7.E7.AB.AF.E5."></a><a name=".E4.BD.BF.E7.94.A8parcelables.E8.BF.9B.E"></a>IPC的调用步骤: </strong></p>
<pre><strong style="font-size: 16px;">&nbsp;1. 声明一个接口类型的变量，该接口类型在.aidl文件中定义。</strong></pre>
<pre><strong style="font-size: 16px;"> 2. 实现ServiceConnection。</strong></pre>
<pre><strong style="font-size: 16px;"> 3. 调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递. </strong></pre>
<pre><strong style="font-size: 16px;">&nbsp;4. 在ServiceConnection.onServiceConnected()实现中，你会接收一个IBinder实例(被调用的Service). 调用</strong></pre>
<pre><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; YourInterfaceName.Stub.asInterface((IBinder)service)将参数转换为YourInterface类型。</strong></pre>
<pre><strong style="font-size: 16px;"> 5. 调用接口中定义的方法。 你总要检测到DeadObjectException异常，该异常在连接断开时被抛出。它只会被远程方法抛出。</strong></pre>
<pre><strong style="font-size: 16px;"> 6. 断开连接，调用接口实例中的ApplicationContext.unbindService()</strong></pre>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">下面是整个程序:</strong></p>
<p><strong style="font-size: 16px;"><strong>1. </strong><strong>ITaskCallback.aidl</strong></strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">package com.cmcc.demo;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">interface ITaskCallback {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; void
actionPerformed(int actionId);</strong></p>
<p><strong style="font-size: 16px;">}</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>2.
ITaskBinder.aidl</strong></strong></p>
<p><strong style="font-size: 16px;">package com.cmcc.demo;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">import com.cmcc.demo.ITaskCallback;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">interface ITaskBinder {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
boolean isTaskRunning();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void stopRunningTask();&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void registerCallback(ITaskCallback cb);&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;
void unregisterCallback(ITaskCallback cb);</strong></p>
<p><strong style="font-size: 16px;">}</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>3. &nbsp;MyService.java</strong></strong></p>
<p><strong style="font-size: 16px;"><strong>package</strong> com.cmcc.demo;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.app.Service;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.content.Intent;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.os.IBinder;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.os.RemoteCallbackList;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.os.RemoteException;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.util.Log;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>public</strong> <strong>class</strong> MyService <strong>extends</strong> Service {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; @Override</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onCreate() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service create");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; @Override</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onStart(Intent <u>intent</u>, <strong>int</strong> startId) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service start id=" + startId);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; callback(startId);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; @Override</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> IBinder onBind(Intent t) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service on bind");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>return</strong> mBinder;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; @Override</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onDestroy() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service on destroy");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>super</strong>.onDestroy();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; @Override</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>boolean</strong> onUnbind(Intent intent) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service on unbind");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>return</strong> <strong>super</strong>.onUnbind(intent);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onRebind(Intent intent) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("service on rebind");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>super</strong>.onRebind(intent);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> <strong>void</strong> printf(String str) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.<em>e</em>("TAG", "###################------ " + str + "------");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>void</strong> callback(<strong>int</strong> val) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>final</strong> <strong>int</strong> N = mCallbacks.beginBroadcast();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>for</strong> (<strong>int</strong> i=0; i&lt;N; i++) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>try</strong> {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mCallbacks.getBroadcastItem(i).actionPerformed(val);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <strong>catch</strong> (RemoteException e) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The RemoteCallbackList will take care of removing</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the dead object for us.</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mCallbacks.finishBroadcast();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> <strong>final</strong> ITaskBinder.Stub mBinder = <strong>new</strong> ITaskBinder.Stub() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> stopRunningTask() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>boolean</strong> isTaskRunning() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>return</strong> <strong>false</strong>;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> registerCallback(ITaskCallback cb) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> (cb != <strong>null</strong>) mCallbacks.register(cb);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> unregisterCallback(ITaskCallback cb) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> (cb != <strong>null</strong>) mCallbacks.unregister(cb);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; };</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>final</strong> RemoteCallbackList&lt;ITaskCallback&gt; mCallbacks</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <strong>new</strong> RemoteCallbackList&lt;ITaskCallback&gt;();</strong></p>
<p><strong style="font-size: 16px;">}</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>4.
MyActivity.java</strong></strong></p>
<p><strong style="font-size: 16px;"><strong>package</strong> com.cmcc.demo;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.app.Activity;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.content.ComponentName;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.content.Context;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.content.Intent;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.content.ServiceConnection;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.graphics.Color;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.os.Bundle;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.os.IBinder;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.os.RemoteException;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.util.Log;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.view.View;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.view.ViewGroup;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.view.View.OnClickListener;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.widget.AbsoluteLayout;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.widget.Button;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.widget.LinearLayout;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.widget.RelativeLayout;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> android.widget.TextView;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> java.io.BufferedReader;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> java.io.File;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> java.io.FileOutputStream;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> java.io.FileReader;</strong></p>
<p><strong style="font-size: 16px;"><strong>import</strong> java.io.PrintWriter;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;"><strong>public</strong> <strong>class</strong> MyActivity
<strong>extends</strong> Activity {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> Button btnOk;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> Button btnCancel;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; @Override</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onCreate(Bundle icicle) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>super</strong>.onCreate(icicle);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setContentView(R.layout.<em>test_service</em>);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnOk = (Button)findViewById(R.id.<em>btn_ok</em>);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnCancel = (Button)findViewById(R.id.<em>btn_cancel</em>);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnOk.setText("Start Service");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnCancel.setTag("Stop Service");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnOk.setOnClickListener(<strong>new</strong> OnClickListener()
{</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onClick(View v) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; onOkClick();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnCancel.setOnClickListener(<strong>new</strong> OnClickListener()
{</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onClick(View v) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; onCancelClick();</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }); </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>void</strong> onOkClick() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bundle args = <strong>new</strong> Bundle();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;Intent intent = <strong>new</strong> Intent(<strong>this</strong>, MyService.<strong>class</strong>);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intent.putExtras(args);&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //printf("send intent to start");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //startService(intent);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bindService(intent, mConnection, Context.<em>BIND_AUTO_CREATE</em>);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startService(intent);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>void</strong> onCancelClick() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Intent intent = <strong>new</strong> Intent(<strong>this</strong>, MyService.<strong>class</strong>);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //printf("send intent to stop");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unbindService(mConnection);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //stopService(intent);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> <strong>void</strong> printf(String str) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.<em>e</em>("TAG", "###################------ " + str + "------");</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; ITaskBinder mService;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> ServiceConnection mConnection = <strong>new</strong>
ServiceConnection() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onServiceConnected(ComponentName className,</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBinder service) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mService = ITaskBinder.Stub.<em>asInterface</em>(service);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>try</strong> {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mService.registerCallback(mCallback);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <strong>catch</strong> (RemoteException e) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> onServiceDisconnected(ComponentName
className) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mService = <strong>null</strong>;</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; };</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; </strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; <strong>private</strong> ITaskCallback mCallback = <strong>new</strong>
ITaskCallback.Stub() {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>void</strong> actionPerformed(<strong>int</strong> id) {</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("callback id=" + id);</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</strong></p>
<p><strong style="font-size: 16px;">&nbsp;&nbsp;&nbsp; };</strong></p>
<strong style="font-size: 16px;"><strong>}</strong>
</strong><br><img src ="http://www.cppblog.com/iuranus/aggbug/93040.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-12 17:17 <a href="http://www.cppblog.com/iuranus/archive/2009/08/12/93040.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ROS 机器人操作系统</title><link>http://www.cppblog.com/iuranus/archive/2009/08/11/92947.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 11 Aug 2009 13:18:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/11/92947.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/92947.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/11/92947.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/92947.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/92947.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2009/08/11/92947.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/92947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-11 21:18 <a href="http://www.cppblog.com/iuranus/archive/2009/08/11/92947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IT新时代- 云计算？</title><link>http://www.cppblog.com/iuranus/archive/2009/08/09/92733.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sun, 09 Aug 2009 12:13:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/09/92733.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/92733.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/09/92733.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/92733.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/92733.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:       我不肯定我的标题，但是C/S往B/S已经是趋势，而我却有B/S开发转向了C/S，但是我不忘记新兴IT的发展，直到google出了操作系统，我想云计算终于要放在桌子上谈了。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2009/08/09/92733.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/92733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-09 20:13 <a href="http://www.cppblog.com/iuranus/archive/2009/08/09/92733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux进程通信:管道要点</title><link>http://www.cppblog.com/iuranus/archive/2009/08/09/92717.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sun, 09 Aug 2009 09:24:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/09/92717.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/92717.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/09/92717.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/92717.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/92717.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 管道的认识从command1 | command2 认识开始，到现在做A2DP升华，写一些使用FIFO的要点下来。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;管道一般用于进程间通信，把一个进程的输出通过管道送给另一个进程。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;可以通过popen，pclose尝试实现command1 | command2 。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File *popen(const char * command, const char *open_mode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open_mode: r or w<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File a =popen("uname -a", "r");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fread(buffer, 1, BUFSIZE, a);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s", buffer);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;&gt; Linux Ubuntu&nbsp;8.09..................<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;pipe创建管道<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include &lt;unistd.h&gt;</p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int pipe(int file_description[2]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pipe的参数是由两个文件描述符组成的数组。file_description[0] 用于读管道， file_description[1] 用来写管道。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;命名管道：mkfifo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include &lt;sys/types.h&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include &lt;sys/stat.h&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int mkfifo(const char&nbsp;* filename, mode_t mode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mode: O_RDONLY, O_WRONLY, O_NONBLOCK.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;共四种组合：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_RDONLY:阻塞读方式打开，除非有进程以写方式打开，不然阻塞。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_RDONLY|O_NONBLOCK:&nbsp; 不论怎样，立即返回，总是成功<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;O_WRONLY: 阻塞写方式打开，直到有人来读，不然阻塞<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_WRONLY|O_NONBLOCK: 立即返回，但如果没人以读方式打开，返回-1错误<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FIFO SIZE：#include &lt;limites.h&gt;, PIPE_BUF,&nbsp;default 4096<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;多个进程可以写同一个管道。 
<img src ="http://www.cppblog.com/iuranus/aggbug/92717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-09 17:24 <a href="http://www.cppblog.com/iuranus/archive/2009/08/09/92717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android Framework architecture -- bluez(2) </title><link>http://www.cppblog.com/iuranus/archive/2009/08/07/92522.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Fri, 07 Aug 2009 04:42:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/07/92522.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/92522.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/07/92522.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/92522.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/92522.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bluetooth signal on成功后，要做的就是查找scan了，scan涉及到的东西，如下图：<br><br><img height=611 alt="" src="http://www.cppblog.com/images/cppblog_com/iuranus/bluetooth_setting.jpg" width=656 border=0><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class bluetoothsetting是UI的入口，通过按button scan进入搜索状态，applicaton层调用bluetoothdevice, 接着就是bluetoothservice的调用，&nbsp;bluetoothservice调用native方法，到此全部的java程序结束了。下面的调用都是JNI, cpp实现的。android_server_bluetoothservice.cpp里面实现了navtive方法，最终通过dbus封装，调用HCID deamon 的function DiscoverDevice.</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/92522.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-07 12:42 <a href="http://www.cppblog.com/iuranus/archive/2009/08/07/92522.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android Framework architecture -- bluez(1)</title><link>http://www.cppblog.com/iuranus/archive/2009/08/04/92109.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 03 Aug 2009 16:12:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/08/04/92109.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/92109.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/08/04/92109.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/92109.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/92109.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:        android一词的本义指“机器人”，和robot不同的是它是有AI的，那么同时google也接android这个单词，于2007年11月5日宣布推出基于Linux平台的开源手机操作系统，该平台由操作系统、中间件、用户界面和应用软件组成，号称是首个为移动终端打造的真正开放和完整的移动软件。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2009/08/04/92109.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/92109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-08-04 00:12 <a href="http://www.cppblog.com/iuranus/archive/2009/08/04/92109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>G1硬件配置(spec)</title><link>http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sun, 19 Jul 2009 14:27:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/90549.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/90549.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/90549.html</trackback:ping><description><![CDATA[<div>William, Windy, Steven都买了G1，对于数码狂人的我当然也想一个了，但怪就怪在Iphone没坏呀(上次在三楼掉下来也没问题)，唉，CC不会让我买的，所以还是等把，我这个坏了再买，赫赫赫赫.<br>&nbsp;<br>最近刚好也在做android移植工作，顺便把G1的spec贴出来，有兴趣的看看<br></div>
<div><span style="FONT-SIZE: 14px; COLOR: rgb(44,41,37); LINE-HEIGHT: 22px; FONT-FAMILY: Verdana; BORDER-COLLAPSE: collapse"><img height=486 alt="" src="http://www.cppblog.com/images/cppblog_com/iuranus/G1_W.jpg" width=600 border=0><br>Product Features &amp; Specifications Technical Specifications
<table class=t_table style="TABLE-LAYOUT: fixed; MARGIN-LEFT: 1px; WIDTH: 981px; LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; empty-cells: show" cellSpacing=0>
    <tbody style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Operating System</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Google Android 1.0&nbsp; （最新的是2.0 donut）</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Network Support</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GSM/GPRS/EDGE/HSDPA, UMTS: 1700/2<span class=t_tag style="CURSOR: pointer; LINE-HEIGHT: normal; BORDER-BOTTOM: rgb(255,0,0) 1px solid; WHITE-SPACE: nowrap; WORD-WRAP: break-word" onclick=tagshow(event) href="tag.php?name=100">100</span>MHz, GSM: 850/900/1800/1900MHz&nbsp; 中国也可以用3G哦</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Screen</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">3.2" HVGA (320 x 480px), 65k Color TFT</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Input Method</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Glass Capacitive&nbsp;<span class=t_tag style="CURSOR: pointer; LINE-HEIGHT: normal; BORDER-BOTTOM: rgb(255,0,0) 1px solid; WHITE-SPACE: nowrap; WORD-WRAP: break-word" onclick=tagshow(event) href="tag.php?name=Touch">Touch</span>screen, Slide-out 5-row QWERTY Keyboard, Trackball navigation</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Wi-Fi</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">802.11b/g</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GPS</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GPS navigation capabilities with Google Maps</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Bluetooth</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Bluetooth v2.0+edr</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Camera</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">3.2MP Camera with auto focus</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Storage</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Internal 256MB Storage, External MicroSDHC Slot</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Connection Ports</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">ExtUSB 2.0 Hi-Speed (Mini-USB compatible for data-transfer, charger, and audio port)</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Physical Attributes</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Dimensions: 117.7mm x 55.7mm x 17.1mm, Weight: 158g with battery</td>
        </tr>
    </tbody>
</table>
<br style="LINE-HEIGHT: normal; WORD-WRAP: break-word">Media Support
<table class=t_table style="TABLE-LAYOUT: fixed; MARGIN-LEFT: 1px; WIDTH: 981px; LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; empty-cells: show" cellSpacing=0>
    <tbody style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Audio Support</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Codecs: MP3/WMA/AAC+/MPEG4/WAV/MIDI/Real Audio/Ogg</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Video Support</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Codecs: H.264/3GPP/MPEG4</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Browser</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Google WebKit-based Browser, streaming video</td>
        </tr>
    </tbody>
</table>
<br style="LINE-HEIGHT: normal; WORD-WRAP: break-word"><br style="LINE-HEIGHT: normal; WORD-WRAP: break-word">Bill of Materials
<table class=t_table style="TABLE-LAYOUT: fixed; MARGIN-LEFT: 1px; WIDTH: 981px; LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; empty-cells: show" cellSpacing=0>
    <tbody style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Processor</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Qualcomm MSM7201A @ 528MHz</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Screen</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Sharp 3.2" HVGA LCD, 65k Color TFT</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Capacitive Sensor IC</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Synaptics 1007A</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Storage</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Samsung MCP - 256MB NAND Flash + 128MB DDR SDRAM</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">USB PHY</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">SMSC USB3316</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Wi-Fi</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Texas Instruments WL1251B</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Bluetooth</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Texas Instruments BRF6300</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GPS</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Integrated into Baseband Processor</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Audio</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Integrated into Baseband Processor</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Accele<span class=t_tag style="CURSOR: pointer; LINE-HEIGHT: normal; BORDER-BOTTOM: rgb(255,0,0) 1px solid; WHITE-SPACE: nowrap; WORD-WRAP: break-word" onclick=tagshow(event) href="tag.php?name=rom">rom</span>eter</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Unknown</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">RF Transceiver</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Qualcomm RTR6285 Quad-band GSM/Dual-band UMTS</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Power Management</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">PMIC: Qualcomm PM7540</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word"></td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Power Amp (Quad-band GSM): TriQuint Semiconductor TQS-7M5008</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word"></td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Power Amp (UMTS-2100MHz): Avago ACPM-7381; (UMTS-1700MHz): Avago ACPM-7391</td>
        </tr>
    </tbody>
</table>
</span><br></div>
<img src ="http://www.cppblog.com/iuranus/aggbug/90549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-07-19 22:27 <a href="http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>