<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>flyinweb 's BLOG</title>
<link>http://www.517sou.net</link>
<Description>flyinweb 's BLOG</Description>
<language>zh-cn</language>
<copyright>Copyright 2003-2005 flyinweb</copyright>
<webMaster>shanyiwan@hotmail.com</webMaster>
<image>
	<title>flyinweb 's BLOG</title> 
	<url>http://www.517sou.net/images/logos.gif</url> 
	<link>http://www.517sou.net</link> 
	<description>flyinweb 's BLOG</description> 
</image>
<item><link>http://www.517sou.net/blogview.asp?logID=1415</link><title>在同一台机器上运行多个 MySQL 服务</title><author>flyinweb</author><category>数据库专栏</category><pubDate>2008-11-20 16:13:55</pubDate><guid>http://www.517sou.net/blogview.asp?logID=1415</guid><description><![CDATA[在同一台机器上运行多个&nbsp;MySQL&nbsp;服务&nbsp;&nbsp;<br>&nbsp;<br>**********************************************************&nbsp;<br><br><strong>第一部分,　在一台服务器构建多mysql&nbsp;服务.</strong>&nbsp;<br><br>**********************************************************&nbsp;<br><br><br><strong>一，绪言</strong>&nbsp;<br><br>在Mysql中有一mysqld_multi命令，可用于在一台物理服务器运行多个Mysql服务，今天参考一些文档，亲自测试并通过,真高兴，现将操作过程共享给大家!&nbsp;<br><br>操作系统:Linux&nbsp;2.6.13&nbsp;(Slackware),其它版的Linux应该也差不多.&nbsp;<br><br>数据库:Mysql&nbsp;4.0.17&nbsp;源程序安装(相信最新的5.1.*也差不多，过些天再试试)&nbsp;<br><br>规划:运行4个mysql服务:&nbsp;<br>假设服务器名:db-app&nbsp;(IP为192.168.0.100),&nbsp;<br>假设服务器名:db-app2&nbsp;(IP为192.168.0.101),&nbsp;<br>下文直到第二部分,均为讲述db-app中的mysql,&nbsp;<br><br><br><strong>二,准备</strong>&nbsp;<br><br>用mysql源程序安装,假设在安装时用的configura选择项氯?&nbsp;<br><div class="code_main">./configure&nbsp;--prefix=/usr/local/mysql&nbsp;--datadir=/usr/local/mysql/data1&nbsp;--sysconfdir=/etc&nbsp;</div><br><br>备注:--prefix将MYSQL安装到/usr/local/mysql,&nbsp;--datadir将数据库生成/usr/local/mysql/data1&nbsp;<br>sysconfdir是指定mysql使用到的my.cnf配置文件的搜索路径为/etc&nbsp;<br><br>其他mysql安装过程略.&nbsp;<br><br>根据Mysql管理手册中提到:每个Mysql的服务都可为独立的，所以它都调用一个my.cnf中各自不同的启动选项--就是下文中将提到的GNR值,使用不同的端口,生成各自的套接文件,服务的数据库都是独立的(更多可查阅mysql官方网站的英文管理手册).&nbsp;<br><br>mysqld_multi是管理多个mysqld的服务进程，这些服务进程程序不同的unix&nbsp;socket或是监听于不同的端口。他可以启动、停止和监控当前的服务状态。&nbsp;<br><br>----程序在my.cnf(或是在--config-file自定义的配置文件)中搜索[mysqld#]段，&quot;#&quot;可以是任意的正整数。这个正整数就是在下面提及的段序列，即GNR。段的序号做为mysqld_multi的参数，来区别不同的段，这样你就可以控制特定mysqld进程的启动、停止或得到他的报告信息。这些组里的参数就像启动一个mysqld所需要的组的参数一样。但是，如果使用多服务，必须为每个服务指定一个unix&nbsp;socket或端口(摘自<a href="http://mifor.4dian.org" target="_blank">http://mifor.4dian.org</a>中的使用mysqld_multi程序管理多个MySQL服务&nbsp;)。&nbsp;<br><br>从上述文字可看到多Mysql服务中最重要的就是my.cnf配置文件了.&nbsp;<br><br>现我贴出我的my.cnf文件.-----------------------&nbsp;<br><div class="code_main">[mysqld_multi]&nbsp;<br>mysqld&nbsp;=&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;<br>mysqladmin&nbsp;=&nbsp;/usr/local/mysql/bin/mysqladmin&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;(用一个帐号来启动所有的mysql服务器,因为是用一相同的帐号。那个么这帐号必须都是每个mysql服务都要用的帐号,最好是管理帐号,下面的口令与相同)&nbsp;<br>password&nbsp;=&nbsp;mypaswd&nbsp;<br><br>[mysqld1]&nbsp;<br>port&nbsp;=&nbsp;3306&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock1&nbsp;<br>pid-file=/usr/local/mysql/data1/db-app1.pid&nbsp;<br>log=/usr/local/mysql/data1/db-app.log&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br><br>[mysqld2]&nbsp;<br>port&nbsp;=&nbsp;3307&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock2&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data2/db-app2.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data2&nbsp;<br>log=/usr/local/mysql/data2/db-app.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br><br>[mysqld3]&nbsp;<br>port&nbsp;=&nbsp;3308&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock3&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data3/db-app3.pid3&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data3&nbsp;<br>log=/usr/local/mysql/data3/db-app.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br><br>[mysqld4]&nbsp;<br>port&nbsp;=&nbsp;3309&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock4&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data3/db-app4.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data4&nbsp;<br>log=/usr/local/mysql/data4/db-app.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br><br>[mysqldump]&nbsp;<br>quick&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;16M&nbsp;<br><br>[mysql]&nbsp;<br>no-auto-rehash&nbsp;<br><br>[isamchk]&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;128M&nbsp;<br>read_buffer&nbsp;=&nbsp;2M&nbsp;<br>write_buffer&nbsp;=&nbsp;2M&nbsp;<br><br>[myisamchk]&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;128M&nbsp;<br>read_buffer&nbsp;=&nbsp;2M&nbsp;<br>write_buffer&nbsp;=&nbsp;2M&nbsp;<br><br>[mysqlhotcopy]&nbsp;<br>interactive-timeout&nbsp;</div><br><br>我的配置文件中有mysqld1,mysqld2,mysqld3,mysqld4。就是说我将启动4个mysql服务在同一服务器的不同端口——3306-3309，每datadir所指定的数据库文件路径都是不相同的，都有各自不同的日志文件。其它一些设置可用my.cnf&nbsp;原来的内容.&nbsp;<br><br>ok,&nbsp;重要的my.cnf编好的，现在为配置中不同mysql&nbsp;服务建立各自文件夹和初始数据库等.&nbsp;<br>[mysqld1]是一个默认的,在我们安装mysql时已经有了，所以不用管它.&nbsp;<br>[mysqld2],只要根据配置就的路径为它建立一个目录就可以了.将把该目录改为mysql管理权&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;mkdir&nbsp;/usr/local/mysql/data2</div>&nbsp;<br>建数据库,我们可以把默认的mysql数据库复制过来，以利用其它的mysql帐号,其它数据库根据应用再建立.&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;cp&nbsp;/usr/local/mysql/data1/mysql&nbsp;/usr/local/mysql/data2&nbsp;-R&nbsp;<br>db-app:/&nbsp;#&nbsp;chmod&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data2&nbsp;-R&nbsp;</div><br><br>[mysqld3],[mysqld4],&nbsp;相同.&nbsp;<br><br>我们可能看看这些目录是否都存在.&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;ls&nbsp;-l&nbsp;/usr/local/mysql/&nbsp;<br>drwxr-xr-x&nbsp;6&nbsp;mysql&nbsp;mysql&nbsp;4096&nbsp;Apr&nbsp;9&nbsp;17:54&nbsp;data4&nbsp;<br>drwxr-x---&nbsp;2&nbsp;mysql&nbsp;mysql&nbsp;4096&nbsp;Apr&nbsp;9&nbsp;17:14&nbsp;data1&nbsp;<br>drwxr-xr-x&nbsp;3&nbsp;mysql&nbsp;mysql&nbsp;4096&nbsp;Apr&nbsp;9&nbsp;17:54&nbsp;data2&nbsp;<br>drwxr-xr-x&nbsp;3&nbsp;mysql&nbsp;mysql&nbsp;4096&nbsp;Apr&nbsp;9&nbsp;17:54&nbsp;data3&nbsp;</div><br><br>现在可以通过mysqld_multi启动了。&nbsp;<br><br><strong>三,mysqld_multi命令.</strong>&nbsp;<br><br>使用如下参数来启动mysqld_multi:&nbsp;(注:该命令在mysql的bin目录中,根据上面所提到./configure&nbsp;--prefix=/usr/local/mysql&nbsp;,所以该文件应该在&nbsp;/usr/local/mysq/bin,&nbsp;这得根据你安装时所指定的路径&nbsp;)&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;mysqld_multi&nbsp;[options]&nbsp;{start|stop|report}&nbsp;[GNR[,GNR]...]&nbsp;</div><br><br>start,stop和report是指你想到执行的操作。你可以在单独的服务或是多服务上指定一个操作，区别于选项后面的GNR列表。如果没有指定GNR列表，那么mysqld_multi将在所有的服务中根据选项文件进行操作。&nbsp;<br><br>每一个GNR的值是组的序列号或是一个组的序列号范围。此项的值必须是组名字最后的数字，比如说如果组名为mysqld17，那么此项的值则为17.如果指定一个范围，使用&quot;-&quot;(破折号)来连接二个数字。如GNR的值为10-13,则指组mysqld10到组mysqld13。多个组或是组范围可以在命令行中指定，使用&quot;,&quot;(逗号)隔开。不能有空白的字符(如空格或tab)，在空白字符后面的参数将会被忽略。&nbsp;(注:GNR值就是我们定义my.cnf中mysqld#中的值,我这里只有1-4).&nbsp;<br><br>db-app:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;start&nbsp;1&nbsp;只启动&nbsp;第一个mysql服务,相关文件由my.cnf中mysql1设定.&nbsp;<br><br>db-app:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;stop&nbsp;1&nbsp;启止&nbsp;第一个mysql服务&nbsp;<br><br>db-app:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;start&nbsp;1-4,&nbsp;启动&nbsp;第1至4mysql服务,其实就是我这里的全部.&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;report&nbsp;1-4&nbsp;</div><br><br>查看启动:&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;ps&nbsp;aux&nbsp;<br>root&nbsp;10467&nbsp;0.0&nbsp;0.2&nbsp;2712&nbsp;1300&nbsp;pts/0&nbsp;S&nbsp;18:59&nbsp;0:00&nbsp;/bin/sh&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;--port=3306&nbsp;--socket=/tmp/mysql.sock1&nbsp;<br><br>root&nbsp;10475&nbsp;0.0&nbsp;0.2&nbsp;2712&nbsp;1300&nbsp;pts/0&nbsp;S&nbsp;18:59&nbsp;0:00&nbsp;/bin/sh&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;--port=3307&nbsp;--socket=/tmp/mysql.sock2&nbsp;<br><br>root&nbsp;10482&nbsp;0.0&nbsp;0.2&nbsp;2716&nbsp;1300&nbsp;pts/0&nbsp;S&nbsp;18:59&nbsp;0:00&nbsp;/bin/sh&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;--port=3308&nbsp;--socket=/tmp/mysql.sock3&nbsp;<br><br>root&nbsp;10487&nbsp;0.0&nbsp;0.2&nbsp;2716&nbsp;1300&nbsp;pts/0&nbsp;S&nbsp;18:59&nbsp;0:00&nbsp;/bin/sh&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;--port=3309&nbsp;--socket=/tmp/mysql.sock4&nbsp;</div><br><br>.............................................&nbsp;<br><br><strong>四,客户端访问</strong>&nbsp;<br><br>任何客户端访问都需要指定访问端口.方才能进入指定数据库服务.否则将使用到Mysql默认的端口（3306）所服务的MYSQL。<br><br><br>**********************************************************&nbsp;<br><br><strong>第二部分,　在一台服务器构建多mysql主&nbsp;服务.&nbsp;</strong><br><br>**********************************************************&nbsp;<br><br><br>提示:建立一个帐号,专门用于下面主从复制,本例用的的帐号repl,&nbsp;口令为:&#39;1234567890&#39;,&nbsp;可让其拥有select_priv,&nbsp;reload_priv,process_priv,grant_priv,super_priv,repl_slave_priv,repl_client_priv权限，并能通过任何客户进行访问,即访问客户为&#39;%&#39;。&nbsp;<br><br>主要是修改my.cnf中的内容,让每个mysql生成自己的bin-log文件及各自的运行环境，现贴上我的my.cnf全部内容,相关参数与请参考mysql&nbsp;官文手册.&nbsp;<br><div class="code_main">#[client]&nbsp;<br>#password&nbsp;=&nbsp;your_password&nbsp;<br>#port&nbsp;=&nbsp;3306&nbsp;<br>#socket&nbsp;=&nbsp;/tmp/mysql.sock&nbsp;<br><br>[mysqld_multi]&nbsp;<br>mysqld&nbsp;=&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;<br>mysqladmin&nbsp;=&nbsp;/usr/local/mysql/bin/mysqladmin&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>password&nbsp;=&nbsp;mypasswd&nbsp;<br>[mysqld1]&nbsp;<br>port&nbsp;=&nbsp;3306&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock1&nbsp;<br>skip-locking&nbsp;<br>pid-file=/usr/local/mysql/data/net-app1a.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data&nbsp;<br>log=/usr/local/mysql/data/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-slow-queries=/usr/local/mysql/data/slowquery.log&nbsp;<br>long_query_time&nbsp;=&nbsp;2&nbsp;<br>key_buffer&nbsp;=&nbsp;256M&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;1M&nbsp;<br>table_cache&nbsp;=&nbsp;512&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;2M&nbsp;<br>read_buffer_size&nbsp;=&nbsp;2M&nbsp;<br>myisam_sort_buffer_size&nbsp;=&nbsp;64M&nbsp;<br>thread_cache&nbsp;=&nbsp;32&nbsp;<br>query_cache_size&nbsp;=&nbsp;32M&nbsp;<br>thread_concurrency&nbsp;=&nbsp;2&nbsp;<br>max_connections=500&nbsp;<br>log-bin&nbsp;<br>log-bin=/usr/local/mysql/data/app-net1_1-bin&nbsp;<br>server-id&nbsp;=&nbsp;1&nbsp;<br><br>[mysqld2]&nbsp;<br>port&nbsp;=&nbsp;3307&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock2&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data2/net-app1b.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data2&nbsp;<br>log=/usr/local/mysql/data2/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-slow-queries=/usr/local/mysql/data2/slowquery.log&nbsp;<br>long_query_time&nbsp;=&nbsp;10&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;1M&nbsp;<br>table_cache&nbsp;=&nbsp;512&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>read_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>myisam_sort_buffer_size&nbsp;=&nbsp;32M&nbsp;<br>thread_cache&nbsp;=&nbsp;32&nbsp;<br>query_cache_size&nbsp;=&nbsp;16M&nbsp;<br>thread_concurrency&nbsp;=&nbsp;2&nbsp;<br>max_connections=300&nbsp;<br>log-bin&nbsp;<br>log-bin=/usr/local/mysql/data2/app-net1_2-bin&nbsp;<br>server-id&nbsp;=&nbsp;1&nbsp;<br><br>[mysqld3]&nbsp;<br>port&nbsp;=&nbsp;3308&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock3&nbsp;<br>skip-locking&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data3/net-app1c.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data3&nbsp;<br>log=/usr/local/mysql/data3/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-bin&nbsp;<br>log-bin=/usr/local/mysql/data3/app-net1_3-bin&nbsp;<br>server-id&nbsp;=&nbsp;1&nbsp;<br><br>[mysqld4]&nbsp;<br>port&nbsp;=&nbsp;3309&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock4&nbsp;<br>skip-locking&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data1/app-net1d.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data1&nbsp;<br>log=/usr/local/mysql/data1/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-bin&nbsp;<br>log-bin=/usr/local/mysql/data1/app-net1_4-bin&nbsp;<br>server-id&nbsp;=&nbsp;1&nbsp;<br><br>[mysqldump]&nbsp;<br>quick&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;16M&nbsp;<br><br>[mysql]&nbsp;<br>no-auto-rehash&nbsp;<br>#&nbsp;Remove&nbsp;the&nbsp;next&nbsp;comment&nbsp;character&nbsp;if&nbsp;you&nbsp;are&nbsp;not&nbsp;familiar&nbsp;with&nbsp;SQL&nbsp;<br>#safe-updates&nbsp;<br><br>[isamchk]&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;128M&nbsp;<br>read_buffer&nbsp;=&nbsp;2M&nbsp;<br>write_buffer&nbsp;=&nbsp;2M&nbsp;<br><br>[myisamchk]&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;128M&nbsp;<br>read_buffer&nbsp;=&nbsp;2M&nbsp;<br>write_buffer&nbsp;=&nbsp;2M&nbsp;<br>[mysqlhotcopy]&nbsp;<br>interactive-timeout</div>&nbsp;<br><br>**********************&nbsp;<br><br>启动多mysql服务都是相同的,&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;start&nbsp;1-4</div><br><br>**********************************************************&nbsp;<br><br><strong>第三部分,&nbsp;在一台服务器构建多mysql&nbsp;从服务.&nbsp;</strong><br><br>**********************************************************&nbsp;<br><br>构建从服务器的预选准备:&nbsp;建议用mysqld_multi&nbsp;把主服务器的mysql全部停掉.删除数据目录中的所有除数据库目录以外的任何文件(此文中的数据目录库有４个,datadir&nbsp;=&nbsp;/usr/local/mysql/中的&nbsp;data1&nbsp;--&nbsp;data1)．建主从都用相同的数据目录路径．&nbsp;<br><br>用Tar&nbsp;命令把每数据库封装起来，并通过sftp命令put/get到从服务器(db-app1&nbsp;192.168.0.101).&nbsp;<br><br>下列操作供参考:&nbsp;<br>在db-app主机上的操作&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;tar&nbsp;-cf&nbsp;data1.tar&nbsp;/usr/local/mysql/data1<br>db-app:/&nbsp;#&nbsp;tar&nbsp;-cf&nbsp;data2.tar&nbsp;/usr/local/mysql/data2<br>db-app:/&nbsp;#&nbsp;tar&nbsp;-cf&nbsp;data3.tar&nbsp;/usr/local/mysql/data3<br>db-app:/&nbsp;#&nbsp;tar&nbsp;-cf&nbsp;data4.tar&nbsp;/usr/local/mysql/data4&nbsp;</div><br><br>在db-app1主机上的操作&nbsp;<br><div class="code_main">db-app1:/&nbsp;#&nbsp;tar&nbsp;xvf&nbsp;data1.tar&nbsp;<br>db-app1:/&nbsp;#&nbsp;tar&nbsp;xvf&nbsp;data2.tar&nbsp;<br>db-app1:/&nbsp;#&nbsp;tar&nbsp;xvf&nbsp;data3.tar&nbsp;<br>db-app1:/&nbsp;#&nbsp;tar&nbsp;xvf&nbsp;data4.tar&nbsp;</div><br><br>同时，请确认系统帐号mysql是否对主/从服务器的中的mysql数据目录都有操作权限，如果无法确认，你直接更修改这些目录的所有权即可。&nbsp;<br><br>在db-app主机上的操作&nbsp;<br><div class="code_main">db-app:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data1&nbsp;-R&nbsp;<br>db-app:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data2&nbsp;-R&nbsp;<br>db-app:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data3&nbsp;-R&nbsp;<br>db-app:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data4&nbsp;-R</div>&nbsp;<br><br>在db-app1主机上的操作&nbsp;<br><div class="code_main">db-app1:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data1&nbsp;-R&nbsp;<br>db-app2:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data2&nbsp;-R&nbsp;<br>db-app3:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data3&nbsp;-R&nbsp;<br>db-app4:/&nbsp;#&nbsp;chown&nbsp;mysql.mysql&nbsp;/usr/local/mysql/data4&nbsp;-R</div>&nbsp;<br><br>下面就是从服务器上/etc/my.cnf的全部内容.&nbsp;<br><br>提示:下面的my.cnf中将会提到一个帐号:repl,&nbsp;口令为:&#39;1234567890&#39;,&nbsp;这个帐号就是上面专门建立的。&nbsp;<br><br>其实都一样,主要是修改my.cnf中的内容,让每个从mysql通过主mysql的不同的端口,去获取各自bin-log来更新自生的数据库内容．现贴上我的my.cnf全部内容(从服务器),相关参数与请参考mysql&nbsp;官文手册.&nbsp;<br><br><br><div class="code_main">#[client]&nbsp;<br>#password&nbsp;=&nbsp;your_password&nbsp;<br>#port&nbsp;=&nbsp;3306&nbsp;<br>#socket&nbsp;=&nbsp;/tmp/mysql.sock&nbsp;<br><br>[mysqld_multi]&nbsp;<br>mysqld&nbsp;=&nbsp;/usr/local/mysql/bin/mysqld_safe&nbsp;<br>mysqladmin&nbsp;=&nbsp;/usr/local/mysql/bin/mysqladmin&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>password&nbsp;=&nbsp;netmoniit&nbsp;<br><br>[mysqld1]&nbsp;<br>port&nbsp;=&nbsp;3306&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock1&nbsp;<br>skip-locking&nbsp;<br>pid-file=/usr/local/mysql/data/net-app1a.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data&nbsp;<br>log=/usr/local/mysql/data/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-slow-queries=/usr/local/mysql/data/slowquery.log&nbsp;<br>long_query_time&nbsp;=&nbsp;2&nbsp;<br>key_buffer&nbsp;=&nbsp;256M&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;1M&nbsp;<br>table_cache&nbsp;=&nbsp;512&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;2M&nbsp;<br>read_buffer_size&nbsp;=&nbsp;2M&nbsp;<br>myisam_sort_buffer_size&nbsp;=&nbsp;64M&nbsp;<br>thread_cache&nbsp;=&nbsp;32&nbsp;<br>query_cache_size&nbsp;=&nbsp;32M&nbsp;<br>thread_concurrency&nbsp;=&nbsp;2&nbsp;<br>max_connections=500&nbsp;<br>server-id&nbsp;=&nbsp;2&nbsp;<br>master-host&nbsp;=&nbsp;192.168.0.100&nbsp;<br>master-user&nbsp;=&nbsp;&#39;repl&#39;&nbsp;<br>master-password&nbsp;=&nbsp;&#39;1234567890&#39;&nbsp;<br>master-port&nbsp;=&nbsp;3309&nbsp;<br>report-host&nbsp;=&nbsp;net-app1&nbsp;<br>master-connect-retry&nbsp;=&nbsp;30&nbsp;<br>log-bin&nbsp;<br>log-slave-updates&nbsp;<br><br>[mysqld2]&nbsp;<br>port&nbsp;=&nbsp;3307&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock2&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data2/net-app1b.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data2&nbsp;<br>log=/usr/local/mysql/data2/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-slow-queries=/usr/local/mysql/data2/slowquery.log&nbsp;<br>long_query_time&nbsp;=&nbsp;10&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;1M&nbsp;<br>table_cache&nbsp;=&nbsp;512&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>read_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>myisam_sort_buffer_size&nbsp;=&nbsp;32M&nbsp;<br>thread_cache&nbsp;=&nbsp;32&nbsp;<br>query_cache_size&nbsp;=&nbsp;16M&nbsp;<br>thread_concurrency&nbsp;=&nbsp;2&nbsp;<br>max_connections=300&nbsp;<br>server-id&nbsp;=&nbsp;2&nbsp;<br>master-host&nbsp;=&nbsp;192.168.0.100&nbsp;<br>master-user&nbsp;=&nbsp;&#39;repl&#39;&nbsp;<br>master-password&nbsp;=&nbsp;&#39;1234567890&#39;&nbsp;<br>master-port&nbsp;=&nbsp;3309&nbsp;<br>report-host&nbsp;=&nbsp;net-app1&nbsp;<br>master-connect-retry&nbsp;=&nbsp;30&nbsp;<br>log-bin&nbsp;<br>log-slave-updates&nbsp;<br><br>[mysqld3]&nbsp;<br>port&nbsp;=&nbsp;3308&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock3&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data3/net-app1c.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data3&nbsp;<br>log=/usr/local/mysql/data3/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-slow-queries=/usr/local/mysql/data3/slowquery.log&nbsp;<br>long_query_time&nbsp;=&nbsp;10&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;1M&nbsp;<br>table_cache&nbsp;=&nbsp;512&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>read_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>myisam_sort_buffer_size&nbsp;=&nbsp;32M&nbsp;<br>thread_cache&nbsp;=&nbsp;32&nbsp;<br>query_cache_size&nbsp;=&nbsp;16M&nbsp;<br>thread_concurrency&nbsp;=&nbsp;2&nbsp;<br>max_connections=300&nbsp;<br>server-id&nbsp;=&nbsp;2&nbsp;<br>master-host&nbsp;=&nbsp;192.168.0.100&nbsp;<br>master-user&nbsp;=&nbsp;&#39;repl&#39;&nbsp;<br>master-password&nbsp;=&nbsp;&#39;1234567890&#39;&nbsp;<br>master-port&nbsp;=&nbsp;3309&nbsp;<br>report-host&nbsp;=&nbsp;net-app1&nbsp;<br>master-connect-retry&nbsp;=&nbsp;30&nbsp;<br>log-bin&nbsp;<br>log-slave-updates&nbsp;<br><br>[mysqld3]&nbsp;<br>port&nbsp;=&nbsp;3308&nbsp;<br>socket&nbsp;=&nbsp;/tmp/mysql.sock4&nbsp;<br>pid-file&nbsp;=&nbsp;/usr/local/mysql/data4/net-app1d.pid&nbsp;<br>datadir&nbsp;=&nbsp;/usr/local/mysql/data4&nbsp;<br>log=/usr/local/mysql/data4/net-app1.log&nbsp;<br>user&nbsp;=&nbsp;mysql&nbsp;<br>log-slow-queries=/usr/local/mysql/data4/slowquery.log&nbsp;<br>long_query_time&nbsp;=&nbsp;10&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;1M&nbsp;<br>table_cache&nbsp;=&nbsp;512&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>read_buffer_size&nbsp;=&nbsp;1M&nbsp;<br>myisam_sort_buffer_size&nbsp;=&nbsp;32M&nbsp;<br>thread_cache&nbsp;=&nbsp;32&nbsp;<br>query_cache_size&nbsp;=&nbsp;16M&nbsp;<br>thread_concurrency&nbsp;=&nbsp;2&nbsp;<br>max_connections=300&nbsp;<br>server-id&nbsp;=&nbsp;2&nbsp;<br>master-host&nbsp;=&nbsp;192.168.0.100&nbsp;<br>master-user&nbsp;=&nbsp;&#39;repl&#39;&nbsp;<br>master-password&nbsp;=&nbsp;&#39;1234567890&#39;&nbsp;<br>master-port&nbsp;=&nbsp;3309&nbsp;<br>report-host&nbsp;=&nbsp;net-app1&nbsp;<br>master-connect-retry&nbsp;=&nbsp;30&nbsp;<br>log-bin&nbsp;<br>log-slave-updates&nbsp;<br><br>[mysqldump]&nbsp;<br>quick&nbsp;<br>max_allowed_packet&nbsp;=&nbsp;16M&nbsp;<br><br>[mysql]&nbsp;<br>no-auto-rehash&nbsp;<br>#&nbsp;Remove&nbsp;the&nbsp;next&nbsp;comment&nbsp;character&nbsp;if&nbsp;you&nbsp;are&nbsp;not&nbsp;familiar&nbsp;with&nbsp;SQL&nbsp;<br>#safe-updates&nbsp;<br><br>[isamchk]&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;128M&nbsp;<br>read_buffer&nbsp;=&nbsp;2M&nbsp;<br>write_buffer&nbsp;=&nbsp;2M&nbsp;<br><br>[myisamchk]&nbsp;<br>key_buffer&nbsp;=&nbsp;128M&nbsp;<br>sort_buffer_size&nbsp;=&nbsp;128M&nbsp;<br>read_buffer&nbsp;=&nbsp;2M&nbsp;<br>write_buffer&nbsp;=&nbsp;2M&nbsp;<br><br>[mysqlhotcopy]&nbsp;<br>interactive-timeout</div>&nbsp;<br><br>****************************************&nbsp;<br><br>在功告成,现在分别启动两台主机上的多mysql服务，这样，每个主服务的每个mysql有变化，都会自动复制／更新到从服务器对应的数据库中。&nbsp;<br><br><div class="code_main">db-app:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;start&nbsp;1-4&nbsp;<br>db-app1:/&nbsp;#&nbsp;/usr/local/mysq/bin/mysqld_multi&nbsp;--config-file=/etc/my.cnf&nbsp;start&nbsp;1-4</div>&nbsp;<br><br>********************&nbsp;<br><br><br><strong>五,未来测试,&nbsp;</strong><br><br>一个多主一从的Mysql服务器复制解决方案!　<br>结构如下．&nbsp;<br><br>就是有主服务器Server&nbsp;A&nbsp;,&nbsp;Server&nbsp;B和从服务器&nbsp;Server&nbsp;C,&nbsp;A&nbsp;和&nbsp;B运行着不同的数据库应用,&nbsp;假设数据库名都不同。Server&nbsp;C（假设这三台ＰＣ上都只运行了一个mysql服务），包括了Ａ了Ｂ服务器的所有Mysql&nbsp;用户及相同的访问权限,&nbsp;并集成在一个Mysql服务中.&nbsp;C通过主/从方式复制Ａ和Ｂ的数据库。&nbsp;<br><br><br>就是差不就是把两个主服务器的mysql合并到一个从服务器中。]]></description></item><item><link>http://www.517sou.net/blogview.asp?logID=1414</link><title>在 Bash shell 中工作</title><author>flyinweb</author><category>技术文摘</category><pubDate>2008-11-20 12:39:08</pubDate><guid>http://www.517sou.net/blogview.asp?logID=1414</guid><description><![CDATA[在&nbsp;Bash&nbsp;shell&nbsp;中工作<br><strong>简介</strong><br>级别：&nbsp;中级<br><a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/authors.html"><font color="#5c81a7">Robert&nbsp;J.&nbsp;Brunner</font></a>&nbsp;(<a target="_blank" href="mailto:rb@ncsa.uiuc.edu?subject=在&nbsp;Bash&nbsp;shell&nbsp;中工作"><font color="#5c81a7">rb@ncsa.uiuc.edu</font></a>),&nbsp;NCSA&nbsp;研究专家，天文学助理教授,&nbsp;University&nbsp;of&nbsp;Illinois,&nbsp;Urbana-Champaign<br>2006&nbsp;年&nbsp;8&nbsp;月&nbsp;10&nbsp;日<br>获得关于&nbsp;Bash&nbsp;shell&nbsp;的简介，您可以在几乎任何基于&nbsp;UNIX®&nbsp;的操作系统中使用&nbsp;Bash&nbsp;shell。Bash&nbsp;是一种成熟的、功能强大而易于使用的&nbsp;shell，并且可以免费获得。本教程提供了&nbsp;Bash&nbsp;的简史，以此说明了&nbsp;Bash&nbsp;shell&nbsp;和其他一些常用的&nbsp;UNIX&nbsp;shell&nbsp;之间的区别，并且还提供了&nbsp;Bash&nbsp;中可用的主要特性的概述。然后，您将了解更多关于&nbsp;UNIX&nbsp;文件系统的知识，如何使用目录和文件，以及自定义&nbsp;Bash&nbsp;的外观和行为的几种方法。最后，本教程以对&nbsp;Bash&nbsp;的作业控制功能的讨论作为全文的结束。<br>开始之前<br>了解本教程中包含的内容以及如何最好地利用本教程。<br><strong>关于本教程</strong><br>本教程提供了关于&nbsp;Bash&nbsp;的基本概述。在阅读了本教程之后，您应该能够在运行&nbsp;Bash&nbsp;的&nbsp;UNIX®&nbsp;终端中执行基本的操作。其中包括在文件系统中进行移动、使用文件和目录以及运行基本的命令。<br><strong>目标</strong><br>本教程面向那些想要学习如何使用&nbsp;Bash&nbsp;直接通过命令行与计算机进行交互的读者。如果您的计算机运行&nbsp;Linux®、Mac&nbsp;OS®&nbsp;X&nbsp;或其他的&nbsp;UNIX&nbsp;系统，并且您想要了解如何开始使用&nbsp;Bash&nbsp;进行工作，那么本教程正是为您准备的。<br><br><strong>先决条件</strong><br>本教程没有任何先决条件。&nbsp;<br><br><strong>系统要求</strong><br>本教程没有任何系统要求，也就是说，您可以仅通过阅读来了解关于&nbsp;Bash&nbsp;的知识。然而，要从本教程中获得最大的收益，您需要能够尝试本教程中提出的相应的技巧。这需要一个可以使用的&nbsp;Bash&nbsp;shell，最好是&nbsp;Version&nbsp;2.05&nbsp;或更高的版本。如果您的计算机上没有安装当前版本的&nbsp;Bash，那么有关如何获取相应副本的信息，请访问&nbsp;Bash&nbsp;主页（请参见<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/resources.html"><font color="#5c81a7">参考资料</font></a>部分）。<br><br>关于&nbsp;Bash&nbsp;的概述大多数计算机用户并不了解他们的计算机中执行所有实际工作的那些技术。例如，在网上冲浪、发送和接收电子邮件或编写文档时，您与计算机进行着很高层次的交互。称为<em>操作系统</em>&nbsp;的软件将用户从底层细节中隔离出来。操作系统中有一个称为<em>内核</em>&nbsp;的特殊组件，它直接与硬件进行交互。&nbsp;<br>许多年来，像&nbsp;Microsoft&nbsp;Windows、K&nbsp;Desktop&nbsp;Environment&nbsp;(KDE)、GNU&nbsp;Network&nbsp;Object&nbsp;Model&nbsp;Environment&nbsp;(GNOME)、Apple&#39;s&nbsp;Aqua&nbsp;和&nbsp;X&nbsp;Consortium&#39;s&nbsp;X11&nbsp;等图形界面都建立在基础操作系统之上，以简化用户通过计算机执行的日常任务。然而，以前并不是这样的。在窗口系统流行之前，计算机用户通过命令行提示符进行操作，直接与内核进行交互以完成他们的工作。因为这种方式使用困难并且容易出错，所以开发了称为&nbsp;<em>shell</em>&nbsp;的新软件层，它可以简化与内核进行通信的任务。&nbsp;<br><strong>UNIX&nbsp;shell&nbsp;的简史</strong>第一个广泛使用的&nbsp;shell&nbsp;由&nbsp;AT&amp;T&nbsp;Bell&nbsp;Labs&nbsp;的&nbsp;Stephen&nbsp;R.&nbsp;Bourne&nbsp;于&nbsp;1974&nbsp;年开发完成，它称为&nbsp;Bourne&nbsp;shell。这个&nbsp;shell&nbsp;使得用户可以更加轻松地与&nbsp;Bell&nbsp;Labs&nbsp;的&nbsp;UNIX&nbsp;研究版本的第七版进行交互。Bourne&nbsp;shell&nbsp;提供了完整的编程语言，该语言允许用户控制程序输入和输出，并且包含了功能强大的表达式匹配功能。&nbsp;<br>差不多在同一时间，University&nbsp;of&nbsp;California,&nbsp;Berkeley&nbsp;开发了另外一种&nbsp;UNIX&nbsp;实现，称为&nbsp;BSD&nbsp;UNIX（表示&nbsp;Berkeley&nbsp;Software&nbsp;Distribution）。在&nbsp;1978&nbsp;年，Berkeley&nbsp;的&nbsp;Bill&nbsp;Joy&nbsp;开发了一种称为&nbsp;C&nbsp;Shell&nbsp;(/bin/csh)&nbsp;的新的&nbsp;UNIX&nbsp;shell，其中添加了一些新的功能，包括作业控制、别名和经过改进的交互功能。而且，对&nbsp;C&nbsp;Shell&nbsp;的编程特性进行了改进，使其更接近于&nbsp;C&nbsp;编程语言。然而，其中的一些改进却使得&nbsp;shell&nbsp;脚本的开发和维护变得更复杂。&nbsp;<br>随后又开发出了其他的&nbsp;shell，包括&nbsp;Korn&nbsp;shell&nbsp;(/bin/ksh)&nbsp;和&nbsp;TC&nbsp;shell&nbsp;(/bin/tcsh)，它们分别对&nbsp;Bourne&nbsp;shell&nbsp;和&nbsp;C&nbsp;Shell&nbsp;这两种原始的&nbsp;shell&nbsp;进行了扩展。虽然这两种&nbsp;shell&nbsp;提供了一些改进，但是它们都存在着各自的缺陷。Korn&nbsp;shell&nbsp;是封闭原始代码的，而&nbsp;TC&nbsp;shell&nbsp;与原始的&nbsp;C&nbsp;Shell&nbsp;一样存在许多脚本编写方面的困难。不久以后，提出了一项国际规范，称为&nbsp;POSIX（可移植操作系统接口）1003.2，该规范说明了&nbsp;shell&nbsp;应该如何与用户进行交互。&nbsp;<br>Bash&nbsp;(/bin/bash)&nbsp;是&nbsp;Bourne-Again&nbsp;SHell&nbsp;的首字母缩写，最初由自由软件基金会的&nbsp;Brian&nbsp;Fox&nbsp;编写，并且克服了以前的各种&nbsp;shell&nbsp;的局限性。Bash&nbsp;构建于&nbsp;Bourne&nbsp;shell&nbsp;的传统之上，它具有下列优点：&nbsp;<br>它提供了功能强大且易于使用的脚本编写语言。&nbsp;<br>它集成了&nbsp;C&nbsp;Shell&nbsp;系列&nbsp;shell&nbsp;的交互式使用的优点。&nbsp;<br>它是免费的，并且完全开放源码。&nbsp;<br>它提供了兼容于&nbsp;POSIX&nbsp;1003.2&nbsp;规范的实现。&nbsp;<br><br><strong>Bash&nbsp;的特性</strong>Bash&nbsp;具有悠久的历史，它提供了一些有价值的特性以改进&nbsp;shell&nbsp;的交互式使用，并且简化了&nbsp;shell&nbsp;脚本的开发，而这些脚本是调用&nbsp;shell&nbsp;特性以实现任务自动化的简单程序。对&nbsp;Bash&nbsp;进行自定义非常容易，可以通过特殊的启动初始化文件和特定的&nbsp;Bash&nbsp;选项来实现。<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section2.html#table1"><font color="#5c81a7">表&nbsp;1</font></a>&nbsp;列举了&nbsp;Bash&nbsp;的一些基本特性，它们改进了&nbsp;Bash&nbsp;的交互式使用。&nbsp;<br><strong>表&nbsp;1.&nbsp;Bash&nbsp;shell&nbsp;的基本特性</strong><br>特性&nbsp;说明<br>命令行编辑<br>这个特性使得您可以轻松地在命令行中移动光标或编辑文本。<br>历史命令<br>这个特性允许您<em>重放</em>&nbsp;或有选择地编辑和恢复一项已在命令行中输入过的命令。<br>IO&nbsp;重定向<br>这个特性使得您可以很容易地更改程序从何处获得输入或将输出发送到何处。<br>别名<br>这个特性允许您为单行的命令创建缩略替代。<br>函数<br>这个特性允许您为多行的命令创建缩略替代。<br>Bash&nbsp;提供了许多有价值的特性以简化&nbsp;shell&nbsp;的开发和维护，但这些内容超出了本教程的范围。<br><br>在&nbsp;Bash&nbsp;的命令提示符处进行工作Bash&nbsp;是运行于&nbsp;UNIX&nbsp;终端中的一个程序。因此，必须启动一个新的终端应用程序来使用它。在缺省情况下，您的系统可能配置为使用不同的&nbsp;shell。要查看您所运行的&nbsp;shell&nbsp;的种类，请在终端窗口的命令提示符处输入&nbsp;echo&nbsp;$SHELL，然后按下&nbsp;<strong>Enter</strong>（或&nbsp;<strong>Return</strong>）。如果应答为&nbsp;/bin/bash，那么就表明您正在运行&nbsp;Bash。如果您得到了不同的应答，那么您可能正在运行不同的&nbsp;shell。&nbsp;<br>要查看您的系统中是否安装了&nbsp;Bash，在命令行中输入&nbsp;whereis&nbsp;bash。这个命令可以定位&nbsp;Bash&nbsp;并且提供该程序的完整路径。如果您的系统中没有安装&nbsp;Bash，那么您可以免费下载并安装最新的版本（请参见<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/resources.html"><font color="#5c81a7">参考资料</font></a>部分）。如果您的系统中已经安装了&nbsp;Bash，那么您可以使用&nbsp;chsh&nbsp;bash&nbsp;命令将缺省&nbsp;shell&nbsp;更改为&nbsp;Bash。请注意，在有的系统中，如&nbsp;MAC&nbsp;OS&nbsp;X，这个命令稍微有些不同。您可以在命令提示符处输入&nbsp;bash，然后按下&nbsp;<strong>Enter</strong>（或&nbsp;<strong>Return</strong>），这样就可以启动一个新的&nbsp;Bash&nbsp;shell（只要您的系统中已经安装了&nbsp;Bash，即使缺省情况下运行的是另一种&nbsp;shell）。&nbsp;<br><strong>在命令行中进行工作</strong>在&nbsp;Bash&nbsp;运行的过程中，您可以通过更改不同的选项，很容易地对其进行自定义。要查看这些选项的列表，请在&nbsp;Bash&nbsp;提示符处输入&nbsp;set&nbsp;-o&nbsp;命令，如<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section3.html#listing1"><font color="#5c81a7">清单&nbsp;1</font></a>&nbsp;所示。请注意，在这个代码清单中，Bash&nbsp;提示符是字符串&nbsp;rb$。该提示符可能与您系统中的提示符有所不同。在本教程后面的内容中，我将介绍如何自定义提示符。&nbsp;<br><strong>清单&nbsp;1.&nbsp;在&nbsp;Bash&nbsp;中设置选项</strong><br><div class="code_main">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>rb$&nbsp;echo&nbsp;$SHELL<br>/bin/bash<br>rb$&nbsp;whereis&nbsp;bash<br>/bin/bash<br>rb$&nbsp;set&nbsp;-o<br>allexport&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>braceexpand&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on<br>emacs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on<br>errexit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>hashall&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on<br>histexpand&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on<br>history&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on<br>ignoreeof&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>interactive-comments&nbsp;&nbsp;&nbsp;&nbsp;on<br>keyword&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>monitor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on<br>noclobber&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>noexec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>noglob&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>nolog&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>notify&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>nounset&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>onecmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>physical&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>posix&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>privileged&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>verbose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>vi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off<br>xtrace&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;off</div><br>&nbsp;&nbsp;<br>如本例所示，Bash&nbsp;中有大量的选项，您可以对它们进行更改以控制&nbsp;Bash&nbsp;如何与用户进行交互。其中一些可以启用的比较有价值的选项包括&nbsp;emacs&nbsp;和&nbsp;history&nbsp;选项。前者允许您使用&nbsp;Emacs&nbsp;键绑定在命令行中进行移动，而后者则表示&nbsp;shell&nbsp;是否应该维护一个执行过的命令的列表，以便您可以轻松地重放它们。&nbsp;<br>如果您从来没有使用过流行的&nbsp;Emacs（或&nbsp;XEmacs）编辑器，那么可能对&nbsp;Emacs&nbsp;键绑定并不很熟悉。然而，它们很容易学习，并且提供了一种功能强大的方法以便在长命令中进行移动。其中一些比较常用的键绑定包括：&nbsp;<br>CTRL+A&nbsp;移动到当前行的起始处。&nbsp;<br>CTRL+E&nbsp;移动到当前行的末尾。&nbsp;<br>CTRL+K&nbsp;删除当前行中光标所在位置后的所有字符。&nbsp;<br>掌握这些（及其相关的）键绑定可以使得在命令提示符处所进行的工作变得更加容易。同样地，启用&nbsp;history&nbsp;选项将使得您可以更轻松地对以前的命令进行重放、或编辑之后再重放。对于大多数的&nbsp;Bash&nbsp;安装，其历史记录的缺省值为最近&nbsp;500&nbsp;条命令，在大多数情况下，这应该已经足够了。但是如果还不够，您可以很容易地更改这个值，在本教程后面的内容中将对这个问题进行介绍。要在历史记录文件中进行前后移动，您可以使用下列键绑定：&nbsp;<br>CTRL+P（表示上一条），或向上箭头键，移动到历史缓冲区中的上一条命令。&nbsp;<br>CTRL+N（表示下一条），或向下箭头键，移动到历史缓冲区中的下一条命令。&nbsp;<br>CTRL+R（表示反向搜索）对以前的命令进行搜索。&nbsp;<br>您还可以使用&nbsp;history&nbsp;命令来显示以前的命令，每条命令都带有它在历史记录缓冲区中的编号。然后，您可以使用该编号，以感叹号&nbsp;(!)&nbsp;作为开始，执行缓冲区中一条特定的命令，比如&nbsp;!382。通过使用感叹号加上一个负数，您还可以对历史记录缓冲区进行相对索引。例如，!-2&nbsp;执行历史记录缓冲区中的倒数第二条命令。因为历史记录缓冲区可以跨越登录会话，所以它为前面的命令的重放提供了一种功能强大的技术。&nbsp;<br>您可能注意到<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section3.html#listing1"><font color="#5c81a7">清单&nbsp;1</font></a>&nbsp;中还介绍了其他的一些选项，根据您的&nbsp;Bash&nbsp;shell&nbsp;的确切版本的不同，其中的一些选项也稍有不同（或者具有不同的缺省值）。通过输入&nbsp;set&nbsp;-o<em>&nbsp;option-name</em>&nbsp;，您可以很容易地设置这些选项；而通过输入&nbsp;set&nbsp;+o<em>&nbsp;option-name</em>&nbsp;，您可以很容易地撤销这些选项。例如，set&nbsp;-o&nbsp;emacs&nbsp;打开了&nbsp;Emacs&nbsp;键绑定选项。&nbsp;<br><br><strong>阅读手册</strong>要了解关于&nbsp;Bash&nbsp;选项或&nbsp;UNIX&nbsp;系统中任何命令的更详细的信息，您可以使用联机&nbsp;UNIX&nbsp;手册。使用&nbsp;man&nbsp;命令来访问它。<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section3.html#listing2"><font color="#5c81a7">清单&nbsp;2</font></a>&nbsp;显示了&nbsp;Bash&nbsp;的手册页面。&nbsp;<br><strong>清单&nbsp;2.&nbsp;阅读&nbsp;Bash&nbsp;的&nbsp;UNIX&nbsp;man&nbsp;页面</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><div class="code_main">rb$&nbsp;man&nbsp;bash<br>BASH(1)&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;BASH(1)<br>NAME<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bash&nbsp;-&nbsp;GNU&nbsp;Bourne-Again&nbsp;SHell<br>SYNOPSIS<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bash&nbsp;[options]&nbsp;[file]<br>COPYRIGHT<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bash&nbsp;&nbsp;is&nbsp;Copyright&nbsp;(C)&nbsp;1989-2004&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation,&nbsp;Inc.<br>DESCRIPTION<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bash&nbsp;is&nbsp;an&nbsp;sh-compatible&nbsp;command&nbsp;language&nbsp;&nbsp;interpreter&nbsp;&nbsp;that&nbsp;&nbsp;executes<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;commands&nbsp;&nbsp;read&nbsp;&nbsp;from&nbsp;&nbsp;the&nbsp;&nbsp;standard&nbsp;&nbsp;input&nbsp;&nbsp;or&nbsp;from&nbsp;a&nbsp;file.&nbsp;&nbsp;Bash&nbsp;also<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;incorporates&nbsp;useful&nbsp;features&nbsp;from&nbsp;the&nbsp;Korn&nbsp;and&nbsp;C&nbsp;shells&nbsp;(ksh&nbsp;and&nbsp;csh).<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bash&nbsp;&nbsp;is&nbsp;&nbsp;intended&nbsp;to&nbsp;be&nbsp;a&nbsp;conformant&nbsp;implementation&nbsp;of&nbsp;the&nbsp;IEEE&nbsp;POSIX<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shell&nbsp;and&nbsp;Tools&nbsp;specification&nbsp;(IEEE&nbsp;Working&nbsp;Group&nbsp;1003.2).<br>OPTIONS<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In&nbsp;addition&nbsp;to&nbsp;the&nbsp;single-character&nbsp;shell&nbsp;options&nbsp;&nbsp;documented&nbsp;&nbsp;in&nbsp;&nbsp;the<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description&nbsp;&nbsp;of&nbsp;the&nbsp;set&nbsp;builtin&nbsp;command,&nbsp;bash&nbsp;interprets&nbsp;the&nbsp;following<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options&nbsp;when&nbsp;it&nbsp;is&nbsp;invoked:<br>:</div><br><br>在&nbsp;Bash&nbsp;中使用文件和目录大多数可能在&nbsp;Bash&nbsp;中进行的工作都将以某种方式与&nbsp;UNIX&nbsp;文件系统协同完成。如果您曾经使用过图形文件浏览器，那么您可能知道文件系统的树型模拟。对于命令行来说，这也是一样的。所有的文件和目录都以&nbsp;/&nbsp;为根，它是文件系统的根节点。<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section4.html#table2"><font color="#5c81a7">表&nbsp;2</font></a>&nbsp;列举了大多数&nbsp;UNIX&nbsp;系统共有的几个标准目录。&nbsp;<br><strong>表&nbsp;2.&nbsp;常用的&nbsp;UNIX&nbsp;系统目录</strong><br>目录&nbsp;描述<br>/<br>这个目录是&nbsp;UNIX&nbsp;系统的根目录，它包含了所有其他的文件。<br>/bin<br>这个目录包含了系统应用程序文件的二进制版本，比如&nbsp;Bash&nbsp;程序本身。<br>/dev<br>这个目录包含了表示诸如磁盘驱动器这样的物理设备的伪文件。<br>/etc<br>这个目录包含了大部分的系统配置文件。<br>/lib<br>这个目录包含了系统应用程序所需的库文件。<br>/opt<br>这个目录包含了可选的系统组件或应用程序。<br>/tmp<br>这个目录包含了系统或用户应用程序使用的临时文件。<br>/usr<br>这个目录包含了用户和非关键的系统应用程序及相关组件。<br>/var<br>这个目录包含了系统应用程序所需的各种文件，如日志或&nbsp;spool&nbsp;文件。<br><strong>在&nbsp;Bash&nbsp;中使用目录</strong><br>有一些&nbsp;UNIX&nbsp;命令使得您可以很容易地创建、列举或删除目录，并且可以更改您当前工作的目录：&nbsp;<br>cd&nbsp;用来将当前工作目录更改为您的&nbsp;home&nbsp;目录。&nbsp;<br>cd&nbsp;dirname&nbsp;将当前工作目录更改为&nbsp;<em>dirname</em>&nbsp;目录。&nbsp;<br>ls&nbsp;dirname&nbsp;列举&nbsp;<em>dirname</em>&nbsp;目录中的内容。&nbsp;<br>mkdir&nbsp;dirname&nbsp;创建一个名为&nbsp;<em>dirname</em>&nbsp;的目录。&nbsp;<br>pwd&nbsp;显示当前工作目录的完整路径。&nbsp;<br>rmdir&nbsp;dirname&nbsp;删除名为&nbsp;<em>dirname</em>&nbsp;的目录。&nbsp;<br>要使用这些程序中的任何一个，只需要在&nbsp;Bash&nbsp;提示符处输入相应的命令（包括所需要的任何目录的名称），然后按下&nbsp;<strong>Enter</strong>（或&nbsp;<strong>Return</strong>）。&nbsp;<br>对于目录的名称，还有几个有用的快捷表示方式：&nbsp;<br>单点号&nbsp;(.)&nbsp;表示当前工作目录。&nbsp;<br>双点号&nbsp;(..)&nbsp;表示当前工作目录的父目录。&nbsp;<br>波浪符号&nbsp;(~)&nbsp;表示您的&nbsp;home&nbsp;目录（通常作为新的&nbsp;Bash&nbsp;shell&nbsp;的起始目录）。&nbsp;<br><a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/listing3"><font color="#5c81a7">清单&nbsp;3</font></a>&nbsp;演示了使用这些命令是非常容易的。&nbsp;<br><strong>清单&nbsp;3.&nbsp;在&nbsp;Bash&nbsp;中使用目录</strong><br><div class="code_main">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>rb$&nbsp;pwd<br>/home/rb<br>rb$&nbsp;mkdir&nbsp;temp<br>rb$&nbsp;cd&nbsp;temp<br>rb$&nbsp;ls&nbsp;<br>rb$&nbsp;cd&nbsp;..<br>rb$&nbsp;pwd<br>/home/rb<br>rb$&nbsp;rmdir&nbsp;temp<br>rb$&nbsp;ls&nbsp;..<br>lost+found&nbsp;&nbsp;&nbsp;&nbsp;rb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root<br>rb$&nbsp;ls&nbsp;/<br>bin&nbsp;&nbsp;&nbsp;etc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;misc&nbsp;&nbsp;proc&nbsp;&nbsp;usr<br>boot&nbsp;&nbsp;home&nbsp;&nbsp;&nbsp;&nbsp;lost+found&nbsp;&nbsp;mnt&nbsp;&nbsp;&nbsp;tmp&nbsp;&nbsp;&nbsp;var<br>dev&nbsp;&nbsp;&nbsp;initrd&nbsp;&nbsp;opt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sbin&nbsp;&nbsp;sys</div><br>前面的清单中所执行的这些命令都非常的简单。首先，显示出您的当前工作目录。然后，创建一个名为&nbsp;temp&nbsp;的新目录，更改到这个新的目录，并列出这个新目录中的内容（因为这个新目录是空的，所以没有显示任何内容）。然后，更改到当前工作目录的父目录，验证已经回到了起始处，然后删除刚创建的临时目录。最后，列出您的&nbsp;home&nbsp;目录的父目录（在本例中为&nbsp;/home）和文件系统的根目录中的内容。&nbsp;<br><br><strong>在&nbsp;Bash&nbsp;中使用文件</strong><br>当在&nbsp;Bash&nbsp;中进行工作时，有许多直接和文件打交道的命令。完整列表的内容相当多，但下面是其中一些比较有价值的命令：&nbsp;<br>cp&nbsp;file1&nbsp;file2&nbsp;将&nbsp;<em>file1</em>&nbsp;复制到&nbsp;<em>file2</em>。&nbsp;<br>mv&nbsp;file1&nbsp;file2&nbsp;将&nbsp;<em>file1</em>&nbsp;重命名为&nbsp;<em>file2</em>。&nbsp;<br>mv&nbsp;filename&nbsp;dirname&nbsp;将&nbsp;<em>filename</em>&nbsp;文件移动到&nbsp;<em>dirname</em>&nbsp;目录。&nbsp;<br>less&nbsp;filename&nbsp;以一种在终端窗口中很容易查看的格式显示文件的内容。&nbsp;<br>file&nbsp;filename&nbsp;显示文件的最佳猜测类型。&nbsp;<br>cat&nbsp;filename&nbsp;显示文件的完整内容。&nbsp;<br>head&nbsp;filename&nbsp;显示文件的前&nbsp;10&nbsp;行（可以对确切的数值进行控制）。&nbsp;<br>tail&nbsp;filename&nbsp;显示文件的最后&nbsp;10&nbsp;行（可以对确切的数值进行控制）。&nbsp;<br>diff&nbsp;file1&nbsp;file2&nbsp;显示&nbsp;<em>file1</em>&nbsp;和&nbsp;<em>file2</em>&nbsp;之间的区别，如果存在。&nbsp;<br>grep&nbsp;string&nbsp;filename&nbsp;根据所指示的字符串搜索目标文件。&nbsp;<br>rm&nbsp;filename&nbsp;删除该文件。&nbsp;<br><a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section4.html#listing4"><font color="#5c81a7">清单&nbsp;4</font></a>&nbsp;显示了使用这些命令是非常容易的。请随意打开一个终端，并自己尝试使用这些命令。请记住，如果您想了解更多的信息，只需要查看该命令的手册页面。例如，输入&nbsp;man&nbsp;cp&nbsp;以阅读复制命令的手册页面。&nbsp;<br><strong>清单&nbsp;4.&nbsp;在&nbsp;Bash&nbsp;中使用文件</strong><br><div class="code_main">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>rb$&nbsp;$&nbsp;cp&nbsp;.bashrc&nbsp;old.bashrc<br>rb$&nbsp;diff&nbsp;old.bashrc&nbsp;.bashrc&nbsp;&nbsp;&nbsp;&nbsp;<br>rb$&nbsp;cat&nbsp;~/.bash_profile&nbsp;<br>source&nbsp;~/.bashrc<br>rb$&nbsp;cat&nbsp;~/.bashrc&nbsp;<br>export&nbsp;PS1=&#39;\u\$&nbsp;&#39;<br>export&nbsp;DERBY_INSTALL=&#39;/opt/Apache/db-derby-10.1.2.1-bin&#39;<br>export&nbsp;CLASSPATH=$DERBY_INSTALL/lib/derby.jar:$DERBY_INSTALL/lib/derbytools.jar:.<br>rb$&nbsp;head&nbsp;-4&nbsp;/usr/share/dict/web2<br>A<br>a<br>aa<br>aal<br>rb$&nbsp;tail&nbsp;-4&nbsp;/usr/share/dict/web2<br>Zythia<br>zythum<br>Zyzomys<br>Zyzzogeton<br>rb$&nbsp;grep&nbsp;exuberance&nbsp;/usr/share/dict/web2&nbsp;<br>exuberance<br>rb$&nbsp;file&nbsp;bash-tutorial.zip&nbsp;<br>bash-tutorial.zip:&nbsp;Zip&nbsp;archive&nbsp;data,&nbsp;at&nbsp;least&nbsp;v2.0&nbsp;to&nbsp;extract<br>rb$&nbsp;file&nbsp;bash-tutorial.xml&nbsp;<br>bash-tutorial.xml:&nbsp;XML&nbsp;document&nbsp;text</div><br>前面的代码清单中演示的这些文件命令都非常的简单，并且提供了复制文件、查看文件内容、搜索字符串在文件中的出现位置、或了解不同文件的类型的示例。首先，使用复制命令来复制&nbsp;.bashrc&nbsp;文件，稍后将对这个文件进行介绍，您可以使用该文件来自定义&nbsp;Bash&nbsp;shell&nbsp;的行为和外观。使用&nbsp;diff&nbsp;命令来检查两个文件是否相同，如果完全相同，则不会显示出任何区别。接下来，使用&nbsp;cat&nbsp;命令显示&nbsp;.bash_profile&nbsp;和&nbsp;.bashrc&nbsp;文件的内容。我将在下一个部分中更加详细地介绍这两个文件的内容。&nbsp;<br>接下来的两个示例是使用&nbsp;head&nbsp;和&nbsp;tail&nbsp;命令来分别显示文件的开头或结尾的若干行。这些示例使用了标志&nbsp;-4，这表示仅显示&nbsp;4&nbsp;行内容，而不是缺省的&nbsp;10&nbsp;行内容。接下来的示例使用&nbsp;grep&nbsp;命令在我的计算机上安装的字典中查找字符串&nbsp;exuberance&nbsp;的匹配项。最后的两个示例使用&nbsp;file&nbsp;命令显示两个不同文件的文件类型。&nbsp;<br>自定义&nbsp;Bash在本教程前面的内容中，我介绍了一些选项，您可以设置这些选项以更改当前&nbsp;Bash&nbsp;shell&nbsp;的行为。对&nbsp;Bash&nbsp;shell&nbsp;进行更改的另一种方法是修改环境变量。您可以使用环境变量来修改&nbsp;Bash&nbsp;的行为，同时，还可以将相关信息传递到在&nbsp;Bash&nbsp;中执行的命令。<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section5.html#table3"><font color="#5c81a7">表&nbsp;3</font></a>&nbsp;列举了一些比较常用的环境变量，您可以在&nbsp;Bash&nbsp;中修改或查看这些环境变量。&nbsp;<br><strong>表&nbsp;3.&nbsp;常用的环境变量</strong><br>变量&nbsp;描述<br>BASH<br>BASH&nbsp;为当前正在运行的&nbsp;Bash&nbsp;shell&nbsp;提供了完整的路径。<br>BASH_VERSION<br>BASH_VERSION&nbsp;提供了当前正在运行的&nbsp;Bash&nbsp;shell&nbsp;的版本。<br>CLASSPATH<br>CLASSPATH&nbsp;提供了搜索&nbsp;Java&nbsp;类文件或&nbsp;Java&nbsp;存档文件的目录列表。<br>HOME<br>HOME&nbsp;是当前用户的&nbsp;home&nbsp;目录。<br>HOSTNAME<br>HOSTNAME&nbsp;是当前计算机的名称。<br>LANG<br>LANG&nbsp;是当前的区域设置，它允许根据不同的国家和语言对&nbsp;shell&nbsp;进行自定义。<br>OSTYPE<br>OSTYPE&nbsp;提供了当前操作系统的描述。<br>PATH<br>PATH&nbsp;是当没有指定完整路径时，搜索命令或应用程序的目录列表。<br>PS1<br>PS1&nbsp;用作主提示符字符串。<br>PS2<br>PS2&nbsp;用作从属提示符字符串。<br>PROMPT_COMMAND<br>应该在显示&nbsp;Bash&nbsp;提示符之前执行这个命令。<br>PWD<br>PWD&nbsp;是当前工作目录的完整路径。<br>SHELL<br>SHELL&nbsp;是当前&nbsp;shell&nbsp;的完整路径名称。<br>USER<br>USER&nbsp;是当前用户的登录名称。<br>要显示一个环境变量的当前值，可以使用&nbsp;echo&nbsp;命令，正如在本教程前面的内容中所演示的，使用该命令来显示&nbsp;SHELL&nbsp;变量的值。要设置一个变量的值，使用&nbsp;$varname=new-value&nbsp;为变量赋值，然后使用&nbsp;export&nbsp;$varname&nbsp;将变量导出到&nbsp;Bash。在修改环境变量时需加小心。如果您犯了错误，那么可能会使&nbsp;shell&nbsp;无法进行响应，或者更糟。通常，您只需修改&nbsp;PATH、PS1&nbsp;或相关的环境变量，因为它们用来定位程序或程序组件，或更改&nbsp;Bash&nbsp;提示符的外观。&nbsp;<br><br><strong>自定义&nbsp;Bash&nbsp;提示符</strong><br>对&nbsp;Bash&nbsp;提示符进行更改，它所提供的强大功能将超出您的想象。您不仅可以更改作为提示符出现的文本，而且您还可以显示当前时间、用户名、计算机名，甚至是当前工作目录。您还可以更改前景和背景颜色，以及显示在终端窗口上的文本的外观。&nbsp;<br>要更改提示符的值，您只需修改&nbsp;PS1&nbsp;环境变量的值。因此，要将您的提示符修改为显示&nbsp;I&nbsp;am&nbsp;the&nbsp;Greatest!$&nbsp;，可以输入&nbsp;PS1=&#39;I&nbsp;am&nbsp;the&nbsp;Greatest!\$&nbsp;&#39;&nbsp;并按下&nbsp;<strong>Enter</strong>&nbsp;（或&nbsp;<strong>Return</strong>）。有几点问题值得讨论，即使是在这个简单的示例中。第一点，完整的字符串必须用引号括起来。第二点，需要在字符串结尾加一个空格字符，这样一来，您所输入的任何文本都将与实际提示符分隔开来。当您需要在终端窗口中对以前的命令（及其输出）进行滚动时，这一点非常重要。最后一点，使用转义序列&nbsp;\$，而不要仅使用一个美元符号。这使得当用户为普通用户时，Bash&nbsp;显示美元符号&nbsp;($)，而当用户为超级用户（即&nbsp;root&nbsp;用户）时，shell&nbsp;则将美元符号更改为井号&nbsp;(#)。如果您需要管理一台计算机，那么这种微妙的变化可能是非常重要的，因为它将帮助提醒您在作为&nbsp;root&nbsp;用户的时候要倍加小心。&nbsp;<br>Bash&nbsp;支持几种特殊的转义序列，这样更容易对提示符的外观进行自定义。有关这些序列的完整讨论，请查阅&nbsp;Bash&nbsp;的联机手册页面或参见<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/resources.html"><font color="#5c81a7">参考资料</font></a>部分。下面是一些比较常用的序列：&nbsp;<br>\u&nbsp;扩展为当前用户的用户名。&nbsp;<br>\h&nbsp;扩展为主机名（直到&nbsp;DNS&nbsp;名称中的第一个点号）。&nbsp;<br>\w&nbsp;扩展为当前工作目录（~&nbsp;表示用户的&nbsp;home&nbsp;目录）。&nbsp;<br>\t&nbsp;扩展为以&nbsp;24&nbsp;小时时钟格式表示的时间&nbsp;(HH:MM:SS)。&nbsp;<br>\A&nbsp;扩展为以&nbsp;24&nbsp;小时时钟格式表示的时间&nbsp;(HH:MM)。&nbsp;<br>\e（ASCII&nbsp;转义字符）将更多的高级选项传递到终端窗口。&nbsp;<br>\[&nbsp;表示非打印字符序列的开始。&nbsp;<br>\]&nbsp;表示非打印字符序列的结束。&nbsp;<br>有了这些序列，现在您可以开始来了解提示符字符串了。例如，在我的&nbsp;.bashrc&nbsp;文件中将提示符字符串设置为&nbsp;PS1=&#39;\u\$&nbsp;&#39;，这将扩展为&nbsp;rb$，因为我作为普通用户登录到我的计算机中，并且用户名为&nbsp;rb。一个更复杂的示例是&nbsp;PS1=&#39;[\A][\u@\h:\w]\$&nbsp;&#39;，它将扩展为（在我的计算机上）[14:14][rb@home:~]$，因为当前的时间为&nbsp;2:14&nbsp;p.m.，即我作为用户&nbsp;<em>rb</em>&nbsp;登录到名为&nbsp;<em>home</em>&nbsp;的计算机上，并且工作于我的&nbsp;home&nbsp;目录中。如果您使用不同的终端窗口登录到多台计算机上，那么这类信息是非常有价值的。在每个&nbsp;Bash&nbsp;shell&nbsp;中适当地设置了提示符后，您可以快速地查看每台计算机由哪个窗口进行响应。&nbsp;<br>另一种快速获得相关信息的好的技术是使用颜色作为标记。如果您曾经在终端窗口中工作过很长时间，并且需要向上滚动以查看某个特殊命令的输出结果，那么您会明白在颜色统一的字符海洋中找出提示符是多么的困难。幸运的是，您可以更改提示符的颜色，这将使它从普通文本中突出显示出来。要说明已提供了颜色代码，可以使用&nbsp;ASCII&nbsp;转义序列&nbsp;\e。实际上，可以在要向&nbsp;Bash&nbsp;传递非打印转义序列的任何时候使用这个序列。对于颜色，可以使用&nbsp;\e[##m&nbsp;或&nbsp;\e[##;##m&nbsp;格式的字符串，其中&nbsp;##&nbsp;字符代表特定的数值。在需要设置文本或背景颜色时，请使用第一种格式。在需要设置文本颜色和表示应该使用特殊特性（如醒目的颜色与浅色）的额外代码时，请使用第二种格式。将这些内容组合到一起，您可以使用&nbsp;PS1=&#39;\e[1;31m[\A]\e[1;34m[\u@\h:\w]\e[0m\$&nbsp;&#39;&nbsp;对以前的提示符自定义颜色。这将使得您的提示符以醒目的红色显示时间，并以醒目的蓝色显示用户名、主机名以及当前工作目录。请注意，在提示符的结尾处将颜色改回了&nbsp;0（这表示没有指定颜色，或恢复到初始的缺省值）。这将使得您能够从所输入的任何命令、或任何命令的输出结果中清楚地辨认出提示符。&nbsp;<br>然而，当使用了这些&nbsp;ASCII&nbsp;转义序列后出现了一个复杂的情况，即每次更改提示符时，Bash&nbsp;会计算您的提示符中到底有多少个字符，并在终端窗口中使用这个值对文本进行换行。因为并不会打印出颜色代码，所以这将影响对&nbsp;shell&nbsp;的长度的计算。要避免对提示符字符串中的非打印字符进行统计，可以使用最后介绍的两种转义序列，\[&nbsp;和&nbsp;\]，使用它们将不显示在提示符中的文本括起来。尽管有时可以在一个非打印序列中包装多个转义序列，但通常最好是一个非打印序列中只放一个转义序列。有了这一点新的认识，您可以把它合并起来，并正确地构建一个复杂的&nbsp;Bash&nbsp;提示符&nbsp;PS1=&#39;\[\e[1;31m\][\A]\[\e[1;34m\][\u@\h:\w]\[\e[0m\]\$&nbsp;&#39;。&nbsp;<br>颜色代码的完整的清单超出了本教程的范围，并且与您所使用的终端的类型密切相关。另外还有一些其他的转义序列，您可以使用它们进一步对终端窗口和&nbsp;Bash&nbsp;提示符的行为和外观进行自定义。有关更详细的信息，请浏览&nbsp;Bash&nbsp;的联机手册页面或研究<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/resources.html"><font color="#5c81a7">参考资料</font></a>部分。&nbsp;<br><br><strong>使用&nbsp;Bash&nbsp;初始化文件</strong><br>毫无疑问，您并不希望每次启动一个新的&nbsp;Bash&nbsp;shell&nbsp;时都去重新设置相应的选项。幸运的是，有几种简单的方式可以用来记录您的自定义信息。当您启动一个新的&nbsp;Bash&nbsp;登录&nbsp;shell（通常发生在打开第一个终端窗口时）时，将读取两个保存了特定自定义信息的文件。第一个文件是&nbsp;/etc/profile，它允许管理员进行系统范围的自定义，而这些自定义规则将统一地应用于每个用户&nbsp;Bash&nbsp;登录&nbsp;shell。第二个文件是&nbsp;~/.bash_profile&nbsp;或&nbsp;~/.profile，这是每个用户自己的自定义文件，它允许您控制对您的&nbsp;Bash&nbsp;shell&nbsp;的设置。请记住，波浪符号表示您的&nbsp;home&nbsp;目录。此外，如果一个文件名以点号开头，则表示它是隐藏的，这样一来就更不容易意外地移动或删除这些文件。因此，通常许多系统配置文件都以点号开头。&nbsp;<br>当您每次启动一个新的&nbsp;Bash&nbsp;shell（在启动了登录&nbsp;shell&nbsp;之后）时，将读取一个新的文件&nbsp;~/.bashrc，而不是&nbsp;~/.bash_profile&nbsp;文件。为了尽量避免混淆，推荐的做法是将所有的自定义设置（如设置选项和环境变量）放到您的&nbsp;~/.bashrc&nbsp;文件中，然后在您的登录初始化文件中引用该文件。通过在您的&nbsp;~/.bash_profile&nbsp;文件末尾添加&nbsp;source&nbsp;~/.bashrc，您可以很容易地完成这项工作，如<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/listing4"><font color="#5c81a7">清单&nbsp;4</font></a>&nbsp;所示。您还可以进行其他的一些自定义工作，包括更改&nbsp;Bash&nbsp;提示符（通过修改&nbsp;PS1&nbsp;环境变量的值），更改终端中显示的颜色，甚至说明在注销&nbsp;Bash&nbsp;是应该执行的命令（使用&nbsp;~/.bash_logout&nbsp;文件）。&nbsp;<br>Bash&nbsp;中的作业控制Bash&nbsp;最强大的功能之一是其协助用户控制不同命令的执行的能力。<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section6.html#figure1"><font color="#5c81a7">图&nbsp;1</font></a>&nbsp;显示了基本&nbsp;UNIX&nbsp;命令的执行模型。在这个模型中，每条命令都有其标准的机制来处理输入/输出&nbsp;(IO)：&nbsp;<br>STDIN（标准输入）允许程序从&nbsp;shell&nbsp;接受输入。&nbsp;<br>STDOUT（标准输出）允许程序将输出传递给&nbsp;shell。&nbsp;<br>STDERR（标准错误）允许程序将错误信息传递给&nbsp;shell。&nbsp;通常，STDIN&nbsp;为键盘，您通过它向命令输入相关信息（正如您在&nbsp;Bash&nbsp;提示符处所进行的工作），而&nbsp;STDOUT&nbsp;和&nbsp;STDERR&nbsp;都是屏幕，将在屏幕上显示相应的结果。然而，您可以重新分配这些&nbsp;IO&nbsp;机制，以便实现其他的输入/输出方式，例如让一条命令从文件读取信息并将输出写回到文件。&nbsp;<br><strong>图&nbsp;1.&nbsp;基本命令的执行</strong><br><img src="attachments/m&#111;nth_0811/85wa_figure1.gif" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br>要更改标准的&nbsp;IO&nbsp;机制，可以使用<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section6.html#table4"><font color="#5c81a7">表&nbsp;4</font></a>&nbsp;中列出的&nbsp;Bash&nbsp;重定向序列。&nbsp;<br><strong>表&nbsp;4.&nbsp;在&nbsp;Bash&nbsp;中进行&nbsp;IO&nbsp;重定向</strong><br>命令序列<br>描述<br>command&nbsp;&nbsp;<br>command&nbsp;&nbsp;将&nbsp;STDIN&nbsp;重定向为读取文件。<br>command&nbsp;&gt;&nbsp;file&nbsp;<br>command&nbsp;&gt;&nbsp;file&nbsp;将&nbsp;STDOUT&nbsp;重定向为写入文件。<br>command&nbsp;&gt;&gt;&nbsp;file&nbsp;<br>command&nbsp;&gt;&gt;&nbsp;file&nbsp;将&nbsp;STDOUT&nbsp;重定向为追加到文件末尾。<br>command&nbsp;2&gt;&nbsp;file&nbsp;<br>command&nbsp;2&gt;&nbsp;file&nbsp;将&nbsp;STDERR&nbsp;重定向为写入文件。<br>command1&nbsp;|&nbsp;command2&nbsp;<br>command1&nbsp;|&nbsp;command2&nbsp;将&nbsp;<em>command1</em>&nbsp;的&nbsp;STDOUT&nbsp;连接到&nbsp;<em>command2</em>&nbsp;的&nbsp;STDIN。<br>您可以使用<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/table4"><font color="#5c81a7">表&nbsp;4</font></a>&nbsp;中的最后一项（称为<em>管道</em>）来串联多个命令。使用管道来连接多个命令，这是&nbsp;UNIX&nbsp;中&nbsp;shell&nbsp;程序开发的一项关键技术，如<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section6.html#figure2"><font color="#5c81a7">图&nbsp;2</font></a>&nbsp;所示。在这个模型中，每个命令完成一项简单的任务，并将其执行结果传递给下一个命令，而由该命令来完成另一项简单的任务，依此类推。例如，您可以使用&nbsp;cat&nbsp;程序将一个文件的内容通过管道传递到&nbsp;grep&nbsp;命令，再由后者将文件中包含给定字符串的每一行通过管道传递到&nbsp;wc&nbsp;命令，而该命令可以统计并显示出查找到了多少个这样的字符串。&nbsp;<br><strong>图&nbsp;2.&nbsp;使用管道连接多个命令</strong><br><img src="attachments/m&#111;nth_0811/fc5i_figure2.gif" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><strong>异步执行</strong>到目前为止，所讨论的命令执行都是同步执行，即一次只能执行一条命令。有些时候，命令或程序需要运行很长一段时间。为了避免妨碍&nbsp;shell&nbsp;的交互式使用，您可以异步地执行命令。要实现这一点，可以在完整的命令行后添加一个和号符号&nbsp;(&amp;)。这会告诉&nbsp;Bash&nbsp;在后台运行该命令，从而允许您继续在前台使用&nbsp;shell。<a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section6.html#listing5"><font color="#5c81a7">清单&nbsp;5</font></a>&nbsp;演示了这种处理方法和其他的作业控制技巧。&nbsp;<br><strong>清单&nbsp;5.&nbsp;演示&nbsp;Bash&nbsp;中的作业控制</strong><br><div class="code_main">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>rb$&nbsp;grep&nbsp;paper.pdf&nbsp;/var/log/httpd/access.log&nbsp;|&nbsp;wc&nbsp;-l<br>5<br>rb$&nbsp;python&nbsp;demo.py&nbsp;&amp;&nbsp;&nbsp;&nbsp;&nbsp;<br>[1]&nbsp;20451<br>rb$&nbsp;jobs<br>[1]+&nbsp;&nbsp;Running&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;python&nbsp;demo.py&nbsp;&amp;<br>rb$&nbsp;fg&nbsp;1<br>python&nbsp;demo.py</div><br><a target="_blank" href="https://www6.software.ibm.com/developerworks/cn/education/aix/au-bash/section6.html#listing5"><font color="#5c81a7">清单&nbsp;5</font></a>&nbsp;演示了两种不同的作业控制技巧。第一个技巧是，grep&nbsp;命令在&nbsp;Apache&nbsp;Web&nbsp;服务器中的&nbsp;access&nbsp;日志文件中搜索&nbsp;<em>paper.pdf</em>&nbsp;字符串。通过管道将这个命令的输出传递到&nbsp;wc&nbsp;-l&nbsp;命令，后者将统计在输入文件中出现了多少包含指定字符串的行。因此，您可以使用这个复合命令来统计某个用户通过&nbsp;Web&nbsp;站点对&nbsp;paper.pdf&nbsp;文件进行了多少次访问。&nbsp;<br>第二个技巧是，将长时间运行的&nbsp;Python&nbsp;程序作为后台任务来调用。Bash&nbsp;以异步的方式在后台启动该作业，并且提供了相应的作业标识符。通过使用&nbsp;jobs&nbsp;命令，您可以列出所有当前正在运行的命令。在这个示例中，只有一个&nbsp;Python&nbsp;程序正在运行，通过使用&nbsp;fg&nbsp;命令，您可以将它提升到前台并以同步的方式运行。这里，我仅介绍了&nbsp;Bash&nbsp;中的基本作业控制功能。如果您真的想称为一名&nbsp;shell&nbsp;专家，那么您需要对该领域的内容进行更深入的研究。&nbsp;<br><strong>结束语</strong><br>本教程提供了关于&nbsp;Bash&nbsp;shell&nbsp;的基本介绍。在回顾了&nbsp;UNIX&nbsp;shell&nbsp;的发展历史和介绍了&nbsp;Bash&nbsp;的基本特性之后，我对几种自定义&nbsp;Bash&nbsp;环境的方法进行了讨论，包括设置选项和环境变量、以及自定义&nbsp;Bash&nbsp;提示符。我还讨论了在命令行提示符处进行工作的一些基本技巧，并以对基本的&nbsp;Bash&nbsp;作业控制技巧的讨论作为全文的结束。]]></description></item><item><link>http://www.517sou.net/blogview.asp?logID=1412</link><title>系统管理员工具包: 充分利用 bash</title><author>flyinweb</author><category>技术文摘</category><pubDate>2008-11-20 12:17:26</pubDate><guid>http://www.517sou.net/blogview.asp?logID=1412</guid><description><![CDATA[系统管理员工具包:&nbsp;充分利用&nbsp;bash<br><br>级别：&nbsp;中级<br>自由撰稿人,&nbsp;Consultant<br>2007&nbsp;年&nbsp;1&nbsp;月&nbsp;08&nbsp;日<br>通过利用&nbsp;Bourne-again&nbsp;shell&nbsp;(bash)&nbsp;的重要组成部分及其功能来简化系统管理任务。Bash&nbsp;是一个流行的&nbsp;Shell，是对原始&nbsp;Bourne&nbsp;和&nbsp;Korn&nbsp;Shell&nbsp;的替代。它提供了印象深刻的系列附加功能，其中包括对脚本环境的改进、广泛的别名技术和用于自动完成各种命令、文件和路径的改进方法。<br>关于本系列<br>典型的&nbsp;UNIX®&nbsp;管理员拥有一套经常用于辅助管理过程的关键实用工具、诀窍和系统。存在各种用于简化不同过程的关键实用工具、命令行链和脚本。其中一些工具来自于操作系统，而大部分的诀窍则来源于长期的经验积累和减轻系统管理员工作压力的要求。本系列文章主要专注于最大限度地利用各种&nbsp;UNIX&nbsp;环境中可用的工具，包括简化异构环境中的管理任务的方法。<br><br><strong>Bash&nbsp;背景介绍</strong><br>UNIX&nbsp;和&nbsp;Linux®&nbsp;环境下的&nbsp;Shell&nbsp;通常可归入两个类别之一，这两个类别基于最初的&nbsp;UNIX&nbsp;版本所附带的原始&nbsp;Shell。它们分别是&nbsp;Bourne&nbsp;Shell&nbsp;和&nbsp;C&nbsp;Shell，后者的独特之处在于其格式和结构类似于&nbsp;C&nbsp;编程语言的格式和结构。&nbsp;<br>Bourne&nbsp;Shell&nbsp;比&nbsp;C&nbsp;Shell&nbsp;更容易使用和理解，但是对于您可能希望在&nbsp;Shell&nbsp;编程环境中完成的更复杂脚本编程，它可能就不太实用了。Korn&nbsp;Shell&nbsp;提供了&nbsp;Bourne&nbsp;Shell&nbsp;的易用性和附加的作业控制扩展（允许您容易地管理多个后台作业）、命令行编辑和历史记录，以及用于简化编程的附加&nbsp;C&nbsp;Shell&nbsp;元素。&nbsp;<br>Bourne-again&nbsp;shell&nbsp;(bash)&nbsp;是一个开放源代码项目，它组合了&nbsp;Bourne&nbsp;Shell&nbsp;的原理、C&nbsp;Shell&nbsp;的编程环境、Korn&nbsp;Shell&nbsp;的扩展功能，以及它自己的许多扩展，这些扩展不仅为&nbsp;Shell&nbsp;脚本编程提供了丰富的环境，而且还用作交互式的&nbsp;shell&nbsp;环境，用于控制并与计算机交互。&nbsp;<br><br><strong>命令行编辑和键绑定</strong><br>bash&nbsp;中的主命令提示符同时提供了编辑命令行的能力和历史记录功能，后者记住各个命令行，以便您能够再次执行它们。&nbsp;<br>编辑功能意味着您可以在当前显示的命令行中向前和向后移动，以做出更改或纠正输入错误。在标准&nbsp;bash&nbsp;形式中，您可以使用光标键来执行基本的移动。更广泛的命令（例如按单词向前和向后移动）可以通过&nbsp;Readline&nbsp;库来控制，该库在缺省情况下同时支持&nbsp;vi&nbsp;和&nbsp;emacs&nbsp;绑定。若要设置编辑模式，可以在命令行上或在引导文件中指定您的首选模式：$&nbsp;set&nbsp;editing-mode&nbsp;emacs。<br>例如，使用&nbsp;emacs&nbsp;编辑模式，以下键绑定将生效：&nbsp;<br>Control-A——此键绑定将当前位置定位到行开头。&nbsp;<br>Control-E——此键绑定将当前位置定位到行尾。&nbsp;<br>Control-K——此键绑定删除截止行尾的所有内容。&nbsp;<br>Meta-B——此键绑定后退一个单词。&nbsp;<br>Meta-F——此键绑定向前推进一个单词。&nbsp;<br>Meta-D——此键绑定删除当前单词。&nbsp;<br>使用内部&nbsp;bind&nbsp;bash&nbsp;命令，您实际上可以随心所欲地将任何键或组合绑定到某个特定的操作。首先，您可以通过使用&nbsp;-P&nbsp;选项（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list1"><font color="#5c81a7">清单&nbsp;1</font></a>）来获取可用命令列表。<br><strong>清单&nbsp;1.&nbsp;使用&nbsp;-P&nbsp;选项来获取可用命令列表</strong><br><div class="code_main">$&nbsp;bind&nbsp;-P&nbsp;<br>abort&nbsp;can&nbsp;be&nbsp;found&nbsp;on&nbsp;&quot;\C-g&quot;,&nbsp;&quot;\C-x\C-g&quot;,&nbsp;&quot;\M-\C-g&quot;.<br>accept-line&nbsp;can&nbsp;be&nbsp;found&nbsp;on&nbsp;&quot;\C-j&quot;,&nbsp;&quot;\C-m&quot;.<br>alias-expand-line&nbsp;is&nbsp;not&nbsp;bound&nbsp;to&nbsp;any&nbsp;keys<br>arrow-key-prefix&nbsp;is&nbsp;not&nbsp;bound&nbsp;to&nbsp;any&nbsp;keys<br>backward-byte&nbsp;is&nbsp;not&nbsp;bound&nbsp;to&nbsp;any&nbsp;keys<br>...<br>yank&nbsp;can&nbsp;be&nbsp;found&nbsp;on&nbsp;&quot;\C-y&quot;.<br>yank-last-arg&nbsp;can&nbsp;be&nbsp;found&nbsp;on&nbsp;&quot;\M-.&quot;,&nbsp;&quot;\M-_&quot;.<br>yank-nth-arg&nbsp;can&nbsp;be&nbsp;found&nbsp;on&nbsp;&quot;\M-\C-y&quot;.<br>yank-pop&nbsp;can&nbsp;be&nbsp;found&nbsp;on&nbsp;&quot;\M-y&quot;.</div><br>\C&nbsp;引用&nbsp;Control&nbsp;键。\M&nbsp;序列引用“Meta”键（某些键盘上的专用键，或者通常为&nbsp;<strong>Alt</strong>&nbsp;键或&nbsp;<strong>Escape</strong>&nbsp;键）。&nbsp;<br>若要设置绑定，您必须指定键序列和要执行的命令，它们之间用分号分隔，并且键序列要用双引号来转义（在极端情况下，您可能需要使用单引号来对该形式进行再次转义）。例如，若要将&nbsp;<strong>Control-B</strong>&nbsp;更改为逐个单词地向后移动，可以使用&nbsp;$&nbsp;bind&nbsp;&quot;\C-b&quot;:backward-word。<br>您甚至可以使用绑定来执行&nbsp;Shell&nbsp;命令（例如，运行某个应用程序）。为此，您必须添加&nbsp;-x&nbsp;选项，这是需要两次转义的一个示例。例如，若要将&nbsp;<strong>Control-E</strong>&nbsp;设置为运行&nbsp;emacs，您要使用以下命令：$&nbsp;bind&nbsp;-x&nbsp;&#39;&quot;\C-e&quot;&#39;:emacs。<br>若要让&nbsp;bash&nbsp;中的键绑定在每次都启用，您可以设置&nbsp;.inputrc&nbsp;文件中的信息（然后此文件将影响所有启用了&nbsp;Readline&nbsp;的应用程序），或者您可以在启动脚本中放置特定的&nbsp;bash&nbsp;绑定，本文稍后将对此进行介绍。&nbsp;<br><br><strong>命令历史记录</strong><br>您输入的每个命令都被记录下来，以便您能够返回到该命令，并再次按原样运行它，或者编辑它并运行编辑后的版本。使用&nbsp;<strong>Control-P</strong>（上一个命令）和&nbsp;<strong>Control-N</strong>（下一个命令），您可以在命令历史记录中向后或向前移动（按反向的年代顺序）。如果已经遍历完前面的所有命令，则只能移动到下一个命令。&nbsp;<br>如果您知道命令的内容，但是想不起它的位置，您可以使用&nbsp;<strong>Control-R</strong>&nbsp;来执行反向智能搜索。这将返回到与您键入的第一个字母相匹配的第一个命令（以反向顺序）；随后键入的字母将使匹配变得越来越明确。一旦找到您想要的命令，按&nbsp;<strong>Return</strong>&nbsp;即可按原样运行它。若要编辑您找到的命令，可以使用光标键（或键绑定）来移动到您希望编辑的位置。&nbsp;<br><br><strong>自定义提示符</strong><br>所有&nbsp;Shell&nbsp;都允许您自定义命令行上显示的提示符，这通常是通过设置&nbsp;PS1&nbsp;变量来实现的。这通常仅限于能够设置某个静态字符串，或者对于&nbsp;Korn&nbsp;Shell，您通常可以设置某个动态值，例如当前目录。&nbsp;<br>Bash&nbsp;进一步扩展了此功能，允许您包含用户名、主机名甚至隐藏字符（例如，设置颜色或设置窗口和&nbsp;Xterm&nbsp;标题所需的转义）。所指定的字符串将紧跟在显示提示符之前求值，因此它始终是最新的。&nbsp;<br>特定动态值的自定义扩展是使用一系列反斜杠字符来实现的。例如，若要设置包含用户名和当前目录最后一部分的典型提示符，可以使用以下命令：PS1=&quot;\u&nbsp;\W$&quot;。<br>更典型的解决方案是显示用户名、主机名、目录，以及美元符号或井号（具体取决于当前用户的&nbsp;UID）。后一个选项在有效用户&nbsp;ID&nbsp;为零&nbsp;(root)&nbsp;时显示一个井号：PS1=&#39;\u@\h:\W&nbsp;\$&nbsp;&quot;。<br><a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#table1"><font color="#5c81a7">表&nbsp;1</font></a>&nbsp;显示了可用扩展的完整列表。<br><strong>表&nbsp;1.&nbsp;可用扩展列表</strong><br>转义字符&nbsp;描述<br>\t<br>\t&nbsp;是时间，格式为&nbsp;HH:MM:SS。<br>\d<br>\d&nbsp;是日期，格式为“工作日名称&nbsp;月份&nbsp;日期”（例如，星期五&nbsp;10&nbsp;月&nbsp;13&nbsp;日）。<br>\n<br>\n&nbsp;是换行。<br>\s<br>\s&nbsp;是&nbsp;Shell&nbsp;名称（通常为&nbsp;bash，如果该&nbsp;Shell&nbsp;是登录&nbsp;Shell，则为&nbsp;&#39;-bash&#39;）。<br>\w<br>\w&nbsp;是当前目录的完整路径。<br>\W<br>\W&nbsp;是当前目录的最后一部分（换句话说，就是&nbsp;&#39;/home/mc&#39;&nbsp;中的&nbsp;&#39;mc&#39;）。<br>\u<br>\u&nbsp;是您的用户名。<br>\h<br>\h&nbsp;是主机名。<br>\#<br>\#&nbsp;是此命令的命令编号（该值在每行递增一）。<br>\!<br>\!&nbsp;是此命令的唯一历史记录编号。<br>\nnn<br>\nnn&nbsp;是由八进制&nbsp;nnn&nbsp;所标识的字符。<br>\$<br>\$&nbsp;在有效&nbsp;UID&nbsp;为零时为&nbsp;#&nbsp;字符，否则为&nbsp;$&nbsp;字符。<br>\\<br>\\&nbsp;是反斜杠。<br>\[<br>\[&nbsp;开始一个转义序列；一般用于颜色设置和标题的终端控制字符。<br>\]<br>\]&nbsp;结束转义序列。<br>转义序列可用于发送终端控制序列，后者又可用于设置颜色和终端标题。由于&nbsp;bash&nbsp;会在每次显示提示符时更新此信息，这会自动更新相应的窗口标题。例如，可以使用<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list2"><font color="#5c81a7">清单&nbsp;2</font></a>&nbsp;中的以下序列来将终端窗口和&nbsp;Xterm&nbsp;标题设置为&nbsp;user@hostname:fullpath，并将提示符设置为&nbsp;hostname:endpath&nbsp;加上适当的终端字符（美元符号或井号）。<br><strong>清单&nbsp;2.&nbsp;设置终端标题和提示符</strong><br>PS1=&quot;&nbsp;\[\033]0;\u@\h:&nbsp;\w\007\]\[\033[31m\]\h&nbsp;\[\033[34m\]\W&nbsp;\$&nbsp;\[\033[00m\]&quot;<br>此外，主机名为&nbsp;root&nbsp;时是红色，为普通用户时为绿色，提示符中的其余部分则设置为青色。&nbsp;<br><br><strong>文件和目录自动完成</strong><br>为帮助提高您的&nbsp;Shell&nbsp;交互速度，bash&nbsp;包含路径名自动完成功能——也就是说，您可以让&nbsp;bash&nbsp;填充路径名的其余部分，或者为您提供可能的展开列表。&nbsp;<br>例如，如果您查看一下当前目录，可以看到一系列不同的子目录（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list3"><font color="#5c81a7">清单&nbsp;3</font></a>）。<br><strong>清单&nbsp;3.&nbsp;当前目录中的子目录</strong><br><div class="code_main">$&nbsp;ls&nbsp;-f<br>back/&nbsp;&nbsp;&nbsp;cheffyhack/&nbsp;&nbsp;edin/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logstomerge/&nbsp;&nbsp;mysql-binlogs/&nbsp;&nbsp;svn/<br>build/&nbsp;&nbsp;cvs/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;install/&nbsp;&nbsp;lost+found/&nbsp;&nbsp;&nbsp;mysqlsizer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vmware/<br>calc/&nbsp;&nbsp;&nbsp;dbdumps/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logs/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my.cnf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statmon/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;webs/</div><br>若要切换到&nbsp;edin&nbsp;目录，您可以输入：$&nbsp;cd&nbsp;edin。或者，使用&nbsp;bash&nbsp;中的自动完成功能，您可以输入&nbsp;$&nbsp;cd&nbsp;e&nbsp;然后按&nbsp;<strong>TAB</strong>&nbsp;键。缺省情况下，这会尝试展开以&nbsp;&#39;e&#39;&nbsp;开头的路径名；此目录中的结果应该是&nbsp;$&nbsp;cd&nbsp;edin。<br>如果存在多个匹配项，则第一次按&nbsp;<strong>TAB</strong>&nbsp;将会失败；第二次按&nbsp;<strong>TAB</strong>&nbsp;将返回匹配的路径列表（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list4"><font color="#5c81a7">清单&nbsp;4</font></a>）。<br><strong>清单&nbsp;4.&nbsp;返回匹配的路径列表</strong><br><div class="code_main">$&nbsp;cd&nbsp;my<br>my.cnf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql-binlogs/&nbsp;mysqlsizer</div><br>展开过程将继续执行，并尽可能将每个部分替换为唯一组件，或者直到无法进一步展开或只存在唯一的路径。例如，请考虑<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list5"><font color="#5c81a7">清单&nbsp;5</font></a>&nbsp;中显示的以下序列。<br><strong>清单&nbsp;5.&nbsp;继续展开</strong><br><div class="code_main">$&nbsp;cd&nbsp;my&nbsp;<br>my.cnf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql-binlogs/&nbsp;mysqlsizer<br>$&nbsp;cd&nbsp;mys&nbsp;<br>$&nbsp;cd&nbsp;mysql&nbsp;&nbsp;<br>mysql-binlogs/&nbsp;mysqlsizer<br>$&nbsp;cd&nbsp;mysqls&nbsp;<br>$&nbsp;cd&nbsp;mysqlsizer</div><br>如果路径名是一个目录，您可以继续展开该路径名的每个部分。<br><br><strong>别名</strong><br>别名是一种简单的机制，允许您为给定的序列提供展开形式。由于别名是一种展开形式而不是替换，它使您可以继续向别名命令添加选项和参数。&nbsp;<br>例如，设置别名&nbsp;(&#39;ll&#39;)&nbsp;是很普遍的，该别名展开为&nbsp;&#39;ls&nbsp;-l&#39;，用于获得目录或文件列表的长清单。可以使用以下命令行来创建别名&nbsp;alias&nbsp;ll=&#39;ls&nbsp;-l&#39;。<br>若要使用该命令，您只需在提示符下输入别名&nbsp;$&nbsp;ll。<br>由于别名不过就是实际命令的别名，因此您可以添加进一步的选项，例如，为了列出目录中的所有文件，您可以使用&nbsp;$&nbsp;ll&nbsp;-a，它实际上展开为&nbsp;$&nbsp;ls&nbsp;-l&nbsp;-a。<br>别名是快速运行命令或使用您经常使用的命令行选项来运行您最喜欢的命令的有效方法。&nbsp;<br><br><strong>使用目录堆栈</strong><br>目录堆栈使您可以将一个或多个目录存储到某个临时区域中，然后再次调回它们。该目录列表的行为就像一个堆栈——您将一个目录压入堆栈顶部，并从顶部弹出一个目录以取回它。&nbsp;<br>若要将某个目录压入堆栈，您可以使用&nbsp;pushd&nbsp;和您希望放在堆栈上的目录——例如，您可以压入当前目录，该目录可由单个句点来标识（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list6"><font color="#5c81a7">清单&nbsp;6</font></a>）。<br><strong>清单&nbsp;6.&nbsp;压入当前目录</strong><br><strong>$&nbsp;pushd&nbsp;.<br>/export/data&nbsp;/export/data</strong><br>Bash&nbsp;使用您压入的目录和当前在堆栈中的所有目录列表（目录之间用一个空格来分隔）来作出响应。通过切换目录并再次压入目录，您可以更清楚地看到这点（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list7"><font color="#5c81a7">清单&nbsp;7</font></a>）。<br><strong>清单&nbsp;7.&nbsp;压入另一个目录</strong><br><div class="code_main">$&nbsp;cd&nbsp;/etc<br>$&nbsp;pushd&nbsp;.<br>/etc&nbsp;/etc&nbsp;/export/data</div><br>使用&nbsp;popd&nbsp;将取走添加到堆栈上的最后一个目录，并切换到该目录（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list8"><font color="#5c81a7">清单&nbsp;8</font></a>）。<br><strong>清单&nbsp;8.&nbsp;使用&nbsp;popd</strong><br><div class="code_main">$&nbsp;cd&nbsp;/usr/local/bin<br>$&nbsp;popd<br>/etc&nbsp;/export/data<br>$&nbsp;pwd</div><br>popd&nbsp;命令在切换到新目录前返回目录列表。&nbsp;<br>当您希望临时切换目录然后返回原始目录时，通常使用此目录功能。为了简化此类情况，通常为&nbsp;bash&nbsp;配置了两个别名，即&nbsp;pu&nbsp;和&nbsp;po，如<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list9"><font color="#5c81a7">清单&nbsp;9</font></a>&nbsp;所示。<br><strong>清单&nbsp;9.&nbsp;Pu&nbsp;和&nbsp;po&nbsp;别名</strong><br><div class="code_main">$&nbsp;alias&nbsp;pu=&#39;pushd&nbsp;.&#39;<br>$&nbsp;alias&nbsp;po=&#39;popd&#39;</div><br>例如，假设您正在某个目录中工作，突然认识到需要在另一个目录中创建一个&nbsp;tar&nbsp;存档（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list10"><font color="#5c81a7">清单&nbsp;10</font></a>）。<br><strong>清单&nbsp;10.&nbsp;使用&nbsp;pu&nbsp;和&nbsp;po&nbsp;来创建&nbsp;tar&nbsp;存档</strong><br><div class="code_main">$&nbsp;pwd<br>/usr/local/bin<br>$&nbsp;pu<br>/usr/local/bin&nbsp;/usr/local/bin<br>$&nbsp;cd&nbsp;/export/data<br>$&nbsp;tar&nbsp;cf&nbsp;webs.tar&nbsp;./webs<br>$&nbsp;po<br>$&nbsp;pwd<br>/usr/local/bin</div><br>尽管目录堆栈系统支持多个目录，但通常是在您临时弹出到其他目录时将它用于一个或两个目录。&nbsp;<br><br><strong>Bash&nbsp;运行时配置文件</strong><br>在登录时，bash&nbsp;支持标准的&nbsp;.profile&nbsp;文件（Bourne&nbsp;Shell&nbsp;所使用的配置文件），除此之外还支持它自己的特定&nbsp;.bash_profile。要使用的文件按如下方式进行选择：&nbsp;<br>如果&nbsp;~/.bash_profile&nbsp;存在，则使用它，否则：&nbsp;<br>如果&nbsp;~/.bash_login&nbsp;存在，则使用它，否则：&nbsp;<br>如果&nbsp;~/.profile&nbsp;存在，则使用它。&nbsp;<br>对于不是作为登录&nbsp;Shell&nbsp;来启动的&nbsp;bash&nbsp;Shell（例如，在使用&nbsp;Xterm&nbsp;或启动某个子&nbsp;Shell&nbsp;的其他应用程序时），bash&nbsp;将寻找&nbsp;~/.bashrc&nbsp;文件（如果它存在的话）。&nbsp;<br>由于&nbsp;.bashrc&nbsp;和&nbsp;.bash_profile&nbsp;的内容不大可能会更改，查找包含<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list11"><font color="#5c81a7">清单&nbsp;11</font></a>&nbsp;所示内容的&nbsp;.bash_profile&nbsp;的情况并不鲜见。<br><strong>清单&nbsp;11.&nbsp;.bash_profile&nbsp;内容</strong><br><div class="code_main">if&nbsp;[&nbsp;-f&nbsp;~/.bashrc&nbsp;];<br>then<br>&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;~/.bashrc<br>fi</div><br>除了这些规则外，那些文件的内容完全取决于您。由于&nbsp;bash&nbsp;环境中存在如此多的自定义，您还可能经常发现&nbsp;.bashrc/.bash_profile&nbsp;内容不过是源于许多其他&nbsp;~/.bash_*&nbsp;脚本内容的包装。例如，您可能将配置划分为：&nbsp;<br>~/.bash_aliases——用于存储所有自定义别名和函数&nbsp;<br>~/.bash_path——用于存储所有路径指定&nbsp;<br>~/.bash_vars——用于存储所有&nbsp;bash&nbsp;变量&nbsp;<br>然后又在&nbsp;.bashrc&nbsp;中引用它们的内容（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list12"><font color="#5c81a7">清单&nbsp;12</font></a>）。<br><strong>清单&nbsp;12.&nbsp;.bashrc&nbsp;内容</strong><br><div class="code_main">if&nbsp;[&nbsp;-f&nbsp;~/.bash_path&nbsp;];&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;~/.bash_path<br>fi<br>if&nbsp;[&nbsp;-f&nbsp;~/.bash_vars&nbsp;];&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;~/.bash_vars<br>fi<br>if&nbsp;[&nbsp;-f&nbsp;~/.bash_aliases&nbsp;];&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;~/.bash_aliases<br>fi</div><br>您应该小心确保以正确的顺序引用那些文件。&nbsp;<br><br><strong>脚本改进</strong><br>bash&nbsp;提供的某些较大改进的最后一个方面是脚本功能。对于大多数&nbsp;Shell，人们经常提到的局限性之一在于，它们具有松散的变量类型、没有数据数组支持、没有用于执行基本的数学或表达式计算的内置功能。所有这些问题都在&nbsp;bash&nbsp;中得到不同程度的解决。&nbsp;<br>bash&nbsp;中的变量可以在使用前声明，并且声明可以包括类型。例如，若要将某个变量声明为整数类型（从而始终将其标识为一个有效数字），可以使用：$&nbsp;declare&nbsp;-i&nbsp;myint。若要同时设置值，可以使用&nbsp;$&nbsp;declare&nbsp;-i&nbsp;myint=235。<br>若要执行基本的算术运算，您可以在&nbsp;$((&nbsp;))&nbsp;中嵌入表达式（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list13"><font color="#5c81a7">清单&nbsp;13</font></a>）。<br><strong>清单&nbsp;13.&nbsp;嵌入表达式以执行基本的算术运算</strong><br><div class="code_main">$&nbsp;echo&nbsp;$((4+3*12))<br>40</div><br>您还可以包括变量（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list14"><font color="#5c81a7">清单&nbsp;14</font></a>）。<br><strong>清单&nbsp;14.&nbsp;包括变量</strong><br><div class="code_main">$&nbsp;echo&nbsp;$((myint+3*12))<br>63</div><br>若要将某个变量声明为数组类型，可以使用&nbsp;$&nbsp;declare&nbsp;-a&nbsp;myarray。<br>您可以通过指定带括号的值列表来添加值：$&nbsp;declare&nbsp;-a&nbsp;myarray=(tom&nbsp;dick&nbsp;harry)。<br>若要获取数组中的值，您可以指定数组引用（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list15"><font color="#5c81a7">清单&nbsp;15</font></a>）。<br><strong>清单&nbsp;15.&nbsp;指定数组引用</strong><br><div class="code_main">$&nbsp;echo&nbsp;${myarray[1]}&nbsp;<br>dick</div><br>您可以使用同样的机制来填充数组，例如，使用文件列表来填充数组（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list16"><font color="#5c81a7">清单&nbsp;16</font></a>）。<br><strong>清单&nbsp;16.&nbsp;使用文件列表来填充数组</strong><br><div class="code_main">$&nbsp;declare&nbsp;-a&nbsp;files=`ls`<br>$&nbsp;echo&nbsp;$files<br>back/&nbsp;build/&nbsp;calc/&nbsp;cheffyhack/&nbsp;cvs/&nbsp;dbdumps/&nbsp;edin/&nbsp;install/&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;logs/&nbsp;logstomerge/&nbsp;lost+found/&nbsp;my.<br>cnf&nbsp;mysql-binlogs/&nbsp;mysqlsizer&nbsp;statmon/&nbsp;svn/&nbsp;vmware/&nbsp;webs/</div><br>而且，通过使用&nbsp;@&nbsp;符号来指定元素，您可以使用数组的整个内容（请参见<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-satbash.html#list17"><font color="#5c81a7">清单&nbsp;17</font></a>）。<br><strong>清单&nbsp;17.&nbsp;使用&nbsp;@&nbsp;符号来指定元素</strong><br><div class="code_main">for&nbsp;file&nbsp;in&nbsp;${files[@]}<br>do<br>&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;$file<br>done</div>这种操作和变量支持使得&nbsp;Shell&nbsp;脚本的许多编程方面变得更加容易了。&nbsp;<br><br><strong>总结</strong><br>相对于传统的&nbsp;Bourne、Korn&nbsp;和&nbsp;C&nbsp;Shell，Bash&nbsp;提供了许多重要改进。这些扩展中的大多数都改善交互式用户（即使用&nbsp;bash&nbsp;作为其与系统交互的主要方法的用户）的体验。有些机制成了习惯，例如路径名自动完成和别名；而其他机制则对个别场合至关重要。目录堆栈机制就是一个很好的例子；当您希望快速访问某个目录而不打断您的思维时，它就变得非常有价值了。&nbsp;<br>无论使用&nbsp;bash&nbsp;Shell&nbsp;中的什么元素，您都会发现一个丰富的环境和几乎无限的自定义系列，您可以使用它们来改进您的交互和环境。<br><br>参考资料&nbsp;<strong>学习</strong><br>您可以参阅本文在&nbsp;developerWorks&nbsp;全球站点上的&nbsp;<a target="_blank" href="http://www.ibm.com/developerworks/aix/library/au-satbash.html?S_TACT=105AGX52&amp;S_CMP=cn-a-aix"><font color="#5c81a7">英文原文</font></a>&nbsp;。<br><a target="_blank" href="http://www.ibm.com/developerworks/cn/views/aix/articles.jsp?view_by=search&amp;search_by=%E7%B3%BB%E7%BB%9F%E7%AE%A1%E7%90%86%E5%91%98%E5%B7%A5%E5%85%B7%E5%8C%85"><font color="#5c81a7">系统管理工具包</font></a>：查看本系列中的其他部分。<br>“<a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/library/au-linuxtogether/index.html"><font color="#5c81a7">让&nbsp;UNIX&nbsp;和&nbsp;Linux&nbsp;一起工作</font></a>”（developerWorks，2006&nbsp;年&nbsp;4&nbsp;月）：这篇文章是让传统&nbsp;UNIX&nbsp;分发版与&nbsp;Linux&nbsp;一起工作的指南。<br><a target="_blank" href="http://www.redbooks.ibm.com/abstracts/SG247186.html?Open"><font color="#5c81a7">Solaris&nbsp;to&nbsp;Linux&nbsp;Migration:&nbsp;A&nbsp;Guide&nbsp;for&nbsp;System&nbsp;Administrators</font></a>：不同的系统使用不同的工具，这本&nbsp;<a href="http://www.ibm.com/cn" target="_blank">IBM</a>&nbsp;红皮书帮助您识别一些重要工具。<br>“<a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/l-memmod/"><font color="#5c81a7">探索&nbsp;Linux&nbsp;内存模型</font></a>”（developerWorks，2006&nbsp;年&nbsp;1&nbsp;月）：理解&nbsp;Linux&nbsp;如何使用内存和交换空间，以及如何在两者之间交换页面和进程。<br>“<a target="_blank" href="http://www.ibm.com/developerworks/cn/views/aix/tutorials.jsp?cv_doc_id=153702"><font color="#996699">在&nbsp;Bash&nbsp;shell&nbsp;中工作</font></a>”（developerWorks，2006&nbsp;年&nbsp;5&nbsp;月）：该教程提供了使用&nbsp;Bourne&nbsp;Again&nbsp;Shell&nbsp;进行所有工作的指南，包括自定义和扩展环境的方法。<br><a target="_blank" href="http://www.gnu.org/software/bash/bash.html"><font color="#5c81a7">Bash</font></a>：Bash&nbsp;是标准&nbsp;Bourne&nbsp;Shell&nbsp;的替代&nbsp;Shell，并且与之具有类似的语法，但同时具备大量的新特性，包括别名、作业控制以及文件和目录名自动完成。<br><a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/"><font color="#5c81a7">AIX®&nbsp;and&nbsp;UNIX</font></a>：访问&nbsp;developerWorks&nbsp;的“AIX&nbsp;and&nbsp;UNIX”专区以拓展您的&nbsp;UNIX&nbsp;技能。<br><a target="_blank" href="http://www.ibm.com/developerworks/cn/aix/newto/"><font color="#5c81a7">AIX&nbsp;and&nbsp;UNIX&nbsp;新手入门</font></a>：访问“AIX&nbsp;and&nbsp;UNIX&nbsp;新手入门”页面以了解更多关于&nbsp;AIX&nbsp;和&nbsp;UNIX&nbsp;的内容。<br><a target="_blank" href="http://www.ibm.com/developerworks/cn/offers/techbriefings/"><font color="#5c81a7">developerWorks&nbsp;技术事件和网络广播</font></a>：跟踪最新的&nbsp;developerWorks&nbsp;技术事件与网络广播。<br><a target="_blank" href="http://www.ibm.com/developerworks/podcast/?S_TACT=105AGX52&amp;S_CMP=cn-a-aix"><font color="#5c81a7">播客</font></a>：收听播客并与&nbsp;<a href="http://www.ibm.com/cn" target="_blank">IBM</a>&nbsp;技术专家保持同步。<br><strong>获得产品和技术</strong><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/downloads/"><font color="#5c81a7"><a href="http://www.ibm.com/cn" target="_blank">IBM</a>&nbsp;试用软件</font></a>：使用&nbsp;<a href="http://www.ibm.com/cn" target="_blank">IBM</a>&nbsp;软件开发您的下一个项目，可直接从&nbsp;developerWorks&nbsp;下载这些试用软件。<br><strong>讨论</strong><br>参与“AIX&nbsp;and&nbsp;UNIX”论坛：&nbsp;<br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?S_TACT=105AGX52&amp;cat=72&amp;S_CMP=cn-a-aix&amp;forum=747"><font color="#5c81a7">AIX&nbsp;5L——技术论坛</font></a>&nbsp;<br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?S_TACT=105AGX52&amp;cat=72&amp;S_CMP=cn-a-aix&amp;forum=905"><font color="#5c81a7">AIX&nbsp;for&nbsp;Developers&nbsp;论坛</font></a>&nbsp;<br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?S_TACT=105AGX52&amp;cat=72&amp;S_CMP=cn-a-aix&amp;forum=907"><font color="#5c81a7">集群系统管理</font></a>&nbsp;<br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?S_TACT=105AGX52&amp;cat=72&amp;S_CMP=cn-a-aix&amp;forum=935"><font color="#5c81a7"><a href="http://www.ibm.com/cn" target="_blank">IBM</a>&nbsp;Support&nbsp;Assistant&nbsp;</font></a><br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?S_TACT=105AGX52&amp;cat=72&amp;S_CMP=cn-a-aix&amp;forum=749"><font color="#5c81a7">性能工具——技术</font></a>&nbsp;<br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?S_TACT=105AGX52&amp;cat=72&amp;S_CMP=cn-a-aix&amp;forum=748"><font color="#5c81a7">虚拟化——技术</font></a>&nbsp;<br><a target="_blank" href="http://www.ibm.com/developerworks/forums/dw_auforums.jsp?S_TACT=105AGX52&amp;S_CMP=cn-a-aix"><font color="#5c81a7">更多“AIX&nbsp;and&nbsp;UNIX”论坛</font></a>&nbsp;<br>访问&nbsp;<a target="_blank" href="http://www.ibm.com/developerworks/blogs/?S_TACT=105AGX52&amp;S_CMP=cn-a-aix"><font color="#5c81a7">developerWorks&nbsp;博客</font></a>，从而加入到&nbsp;developerWorks&nbsp;社区中来。<br><strong>关于作者</strong><img src="attachments/m&#111;nth_0811/2008112012172436167_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012172436167_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br>Martin&nbsp;Brown&nbsp;成为专业作家已经超过&nbsp;8&nbsp;个年头。他所撰写的书籍和文章涵盖了各种各样的主题。他所擅长的领域包括大量开发语言和平台——Perl、Python、Java、JavaScript、Basic、Pascal、Modula-2、C、C++、Rebol、Gawk、Shellscript、Windows、Solaris、Linux、BeOS、Mac&nbsp;OS/X&nbsp;等等——以及&nbsp;Web&nbsp;编程、系统管理与集成。Martin&nbsp;是&nbsp;ServerWatch.com、LinuxToday.com&nbsp;和&nbsp;<a href="http://www.ibm.com/cn" target="_blank">IBM</a>&nbsp;developerWorks&nbsp;的定期投稿者。他也是&nbsp;Computerworld、The&nbsp;Apple&nbsp;Blog&nbsp;和其他站点以及&nbsp;<a href="http://www.microsoft.com/china/homepage/ms.htm" target="_blank"><img src="images/keywords/microsoft.gif" border="0" align="absmiddle"> Microsoft</a>的&nbsp;Subject&nbsp;Matter&nbsp;Expert&nbsp;(SME)&nbsp;的常客。您可以通过他的网站&nbsp;<a target="_blank" href="http://www.mcslp.com/"><font color="#5c81a7">http://www.mcslp.com</font></a>&nbsp;与他联系。]]></description></item><item><link>http://www.517sou.net/blogview.asp?logID=1411</link><title>Bash 实例</title><author>flyinweb</author><category>技术文摘</category><pubDate>2008-11-20 12:10:29</pubDate><guid>http://www.517sou.net/blogview.asp?logID=1411</guid><description><![CDATA[级别：&nbsp;初级<br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#author"><font color="#5c81a7">Daniel&nbsp;Robbins</font></a>&nbsp;(<a target="_blank" href="mailto:drobbins@gentoo.org?subject=Bash&nbsp;实例，第一部分&amp;cc=drobbins@gentoo.org"><font color="#5c81a7">drobbins@gentoo.org</font></a>),&nbsp;总裁兼&nbsp;CEO,&nbsp;Gentoo&nbsp;Technologies,&nbsp;Inc.<br>2000&nbsp;年&nbsp;3&nbsp;月&nbsp;01&nbsp;日<br>通过学习如何使用&nbsp;bash&nbsp;脚本语言编程，将使&nbsp;Linux&nbsp;的日常交互更有趣和有生产力，同时还可以利用那些已熟悉和喜爱的标准&nbsp;UNIX&nbsp;概念（如管道和重定向）。在此三部分系列中，Daniel&nbsp;Robbins&nbsp;将以示例指导您如何用&nbsp;bash&nbsp;编程。他将讲述非常基本的知识（这使此系列十分适合初学者），并在后续系列中逐步引入更高级特性。<br>您可能要问：为什么要学习&nbsp;Bash&nbsp;编程？好，以下是几条令人信服的理由：<br>已经在运行它<br>如果查看一下，可能会发现：您现在正在运行&nbsp;bash。因为&nbsp;bash&nbsp;是标准&nbsp;Linux&nbsp;shell，并用于各种目的，所以，即使更改了缺省&nbsp;shell，bash&nbsp;可能&nbsp;<em>仍</em>&nbsp;在系统中某处运行。因为&nbsp;bash&nbsp;已在运行，以后运行的任何&nbsp;bash&nbsp;脚本都天生是有效利用内存的，因为它们与任何已运行的&nbsp;bash&nbsp;进程共享内存。如果正在运行的工具可以胜任工作，并且做得很好，为什么还要装入一个&nbsp;500K&nbsp;的解释器？&nbsp;<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>已经在使用它<br>不仅在运行&nbsp;bash，实际上，您每天还在与&nbsp;bash&nbsp;打交道。它总在那里，因此学习如何最大限度使用它是有意义的。这样做将使您的&nbsp;bash&nbsp;经验更有趣和有生产力。但是为什么要学习&nbsp;bash&nbsp;<em>编程</em>&nbsp;？很简单，因为您已在考虑如何运行命令、CPing&nbsp;文件以及管道化和重定向输出。为什么不学习一种语言，以便使用和利用那些已熟悉和喜爱的强大省时的概念？命令&nbsp;shell&nbsp;开启了&nbsp;UNIX&nbsp;系统的潜能，而&nbsp;bash&nbsp;正是&nbsp;<em>这个</em>&nbsp;Linux&nbsp;shell。它是您和机器之间的高级纽带。增长&nbsp;bash&nbsp;知识吧，这将自动提高您在&nbsp;Linux&nbsp;和&nbsp;UNIX&nbsp;中的生产力&nbsp;--&nbsp;就那么简单。&nbsp;<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>Bash&nbsp;困惑<br>以错误方式学习&nbsp;bash&nbsp;令人十分困惑。许多新手输入&nbsp;&quot;man&nbsp;bash&quot;&nbsp;来查看&nbsp;bash&nbsp;帮助页，但只得到非常简单和技术方面的&nbsp;shell&nbsp;功能性描述。还有人输入&nbsp;&quot;info&nbsp;bash&quot;（来查看&nbsp;GNU&nbsp;信息文档），只能得到重新显示的帮助页，或者（如果幸运）略为友好的信息文档。<br>尽管这可能使初学者有些失望，但标准&nbsp;bash&nbsp;文档无法满足所有人的要求，它只适合那些已大体熟悉&nbsp;shell&nbsp;编程的人。帮助页中确实有很多极好的技术信息，但对初学者的帮助却有限。<br>这就是本系列的目的所在。在本系列中，我将讲述如何实际使用&nbsp;bash&nbsp;编程概念，以便编写自己的脚本。与技术描述不同，我将以简单的语言为您解释，使您不仅知道事情做什么，还知道应在何时使用。在此三部分系列末尾，您将可以自己编写复杂的&nbsp;bash&nbsp;脚本，并可以自如地使用&nbsp;bash&nbsp;以及通过阅读（和理解）标准&nbsp;bash&nbsp;文档来补充知识。让我们开始吧。<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>环境变量<br>在&nbsp;bash&nbsp;和几乎所有其它&nbsp;shell&nbsp;中，用户可以定义环境变量，这些环境变量在以&nbsp;ASCII&nbsp;字符串存储。环境变量的最便利之处在于：它们是&nbsp;UNIX&nbsp;进程模型的标准部分。这意味着：环境变量不仅由&nbsp;shell&nbsp;脚本独用，而且还可以由编译过的标准程序使用。当在&nbsp;bash&nbsp;中“导出”环境变量时，以后运行的任何程序，不管是不是&nbsp;shell&nbsp;脚本，都可以读取设置。一个很好的例子是&nbsp;vipw&nbsp;命令，它通常允许&nbsp;root&nbsp;用户编辑系统口令文件。通过将&nbsp;EDITOR&nbsp;环境变量设置成喜爱的文本编辑器名称，可以配置&nbsp;vipw，使其使用该编辑器，而不使用&nbsp;vi，如果习惯于&nbsp;xemacs&nbsp;而确实不喜欢&nbsp;vi，那么这是很便利的。<br>在&nbsp;bash&nbsp;中定义环境变量的标准方法是：<br>$&nbsp;myvar=&#39;This&nbsp;is&nbsp;my&nbsp;environment&nbsp;variable!&#39;<br>以上命令定义了一个名为&nbsp;&quot;myvar&quot;&nbsp;的环境变量，并包含字符串&nbsp;&quot;This&nbsp;is&nbsp;my&nbsp;environment&nbsp;variable!&quot;。以上有几点注意事项：第一，在等号&nbsp;&quot;=&quot;&nbsp;的两边没有空格，任何空格将导致错误（试一下看看）。第二个件要注意的事是：虽然在定义一个字时可以省略引号，但是当定义的环境变量值多于一个字时（包含空格或制表键），引号是必须的。<br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><strong>引用细节</strong><br>有关如何在&nbsp;bash&nbsp;中使用引号的非常详尽的信息，请参阅&nbsp;bash&nbsp;帮助页面中的“引用”一节。特殊字符序列由其它值“扩展”（替换）确实使&nbsp;bash&nbsp;中字符串的处理变得复杂。本系列将只讲述最常用的引用功能。&nbsp;<br>第三，虽然通常可以用双引号来替代单引号，但在上例中，这样做会导致错误。为什么呢？因为使用单引号禁用了称为扩展的&nbsp;bash&nbsp;特性，其中，特殊字符和字符系列由值替换。例如，&quot;!&quot;&nbsp;字符是历史扩展字符，bash&nbsp;通常将其替换为前面输入的命令。（本系列文章中将不讲述历史扩展，因为它在&nbsp;bash&nbsp;编程中不常用。有关历史扩展的详细信息，请参阅&nbsp;bash&nbsp;帮助页中的“历史扩展”一节。）尽管这个类似于宏的功能很便利，但我们现在只想在环境变量后面加上一个简单的感叹号，而不是宏。<br>现在，让我们看一下如何实际使用环境变量。这有一个例子：<br>$&nbsp;echo&nbsp;$myvar<br>This&nbsp;is&nbsp;my&nbsp;environment&nbsp;variable!<br>通过在环境变量的前面加上一个&nbsp;$，可以使&nbsp;bash&nbsp;用&nbsp;myvar&nbsp;的值替换它。这在&nbsp;bash&nbsp;术语中叫做“变量扩展”。但是，这样做将怎样：<br>$&nbsp;echo&nbsp;foo$myvarbar<br>foo<br>我们希望回显&nbsp;&quot;fooThis&nbsp;is&nbsp;my&nbsp;environment&nbsp;variable!bar&quot;，但却不是这样。错在哪里？简单地说，bash&nbsp;变量扩展设施陷入了困惑。它无法识别要扩展哪一个变量：$m、$my、$myvar&nbsp;、$myvarbar&nbsp;等等。如何更明确清楚地告述&nbsp;bash&nbsp;引用哪一个变量？试一下这个：<br>$&nbsp;echo&nbsp;foo${myvar}bar<br>fooThis&nbsp;is&nbsp;my&nbsp;environment&nbsp;variable!bar<br>如您所见，当环境变量没有与周围文本明显分开时，可以用花括号将它括起。虽然&nbsp;$myvar&nbsp;可以更快输入，并且在大多数情况下正确工作，但&nbsp;${myvar}&nbsp;却能在几乎所有情况下正确通过语法分析。除此之外，二者相同，将在本系列的余下部分看到变量扩展的两种形式。请记住：当环境变量没有用空白（空格或制表键）与周围文本分开时，请使用更明确的花括号形式。<br>回想一下，我们还提到过可以“导出”变量。当导出环境变量时，它可以自动地由以后运行的任何脚本或可执行程序环境使用。shell&nbsp;脚本可以使用&nbsp;shell&nbsp;的内置环境变量支持“到达”环境变量，而&nbsp;C&nbsp;程序可以使用&nbsp;getenv()&nbsp;函数调用。这里有一些&nbsp;C&nbsp;代码示例，输入并编译它们&nbsp;--&nbsp;它将帮助我们从&nbsp;C&nbsp;的角度理解环境变量：<br><strong>myvar.c&nbsp;--&nbsp;样本环境变量&nbsp;C&nbsp;程序</strong><br>#include&nbsp;<br>#include&nbsp;<br>int&nbsp;main(void)&nbsp;{<br>&nbsp;&nbsp;char&nbsp;*myenvvar=getenv(&quot;EDITOR&quot;);<br>&nbsp;&nbsp;printf(&quot;The&nbsp;editor&nbsp;environment&nbsp;variable&nbsp;is&nbsp;set&nbsp;to&nbsp;%s\n&quot;,myenvvar);<br>}<br>将上面的代码保存到文件&nbsp;myenv.c&nbsp;中，然后发出以下命令进行编译：<br>$&nbsp;gcc&nbsp;myenv.c&nbsp;-o&nbsp;myenv<br>现在，目录中将有一个可执行程序，它在运行时将打印&nbsp;EDITOR&nbsp;环境变量的值（如果有值的话）。这是在我机器上运行时的情况：<br>$&nbsp;./myenv<br>The&nbsp;editor&nbsp;environment&nbsp;variable&nbsp;is&nbsp;set&nbsp;to&nbsp;(null)<br>啊...&nbsp;因为没有将&nbsp;EDITOR&nbsp;环境变量设置成任何值，所以&nbsp;C&nbsp;程序得到一个空字符串。让我们试着将它设置成特定值：<br>$&nbsp;EDITOR=xemacs<br>$&nbsp;./myenv<br>The&nbsp;editor&nbsp;environment&nbsp;variable&nbsp;is&nbsp;set&nbsp;to&nbsp;(null)<br>虽然希望&nbsp;myenv&nbsp;打印值&nbsp;&quot;xemacs&quot;，但是因为还没有导出环境变量，所以它却没有很好地工作。这次让它正确工作：<br>$&nbsp;export&nbsp;EDITOR<br>$&nbsp;./myenv<br>The&nbsp;editor&nbsp;environment&nbsp;variable&nbsp;is&nbsp;set&nbsp;to&nbsp;xemacs<br>现在，如您亲眼所见：不导出环境变量，另一个进程（在本例中是示例&nbsp;C&nbsp;程序）就看不到环境变量。顺便提一句，如果愿意，可以在一行定义并导出环境变量，如下所示：<br>$&nbsp;export&nbsp;EDITOR=xemacs<br>这与两行版本的效果相同。现在该演示如何使用&nbsp;unset&nbsp;来除去环境变量：<br>$&nbsp;unset&nbsp;EDITOR<br>$&nbsp;./myenv<br>The&nbsp;editor&nbsp;environment&nbsp;variable&nbsp;is&nbsp;set&nbsp;to&nbsp;(null)<br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><strong>dirname&nbsp;和&nbsp;basename</strong><br>请注意：dirname&nbsp;和&nbsp;basename&nbsp;不是磁盘上的文件或目录，它们只是字符串操作命令。&nbsp;<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>截断字符串概述<br>截断字符串是将初始字符串截断成较小的独立块，它是一般&nbsp;shell&nbsp;脚本每天执行的任务之一。很多时候，shell&nbsp;脚本需要采用全限定路径，并找到结束的文件或目录。虽然可以用&nbsp;bash&nbsp;编码实现（而且有趣），但标准&nbsp;basename&nbsp;UNIX&nbsp;可执行程序可以极好地完成此工作：<br>$&nbsp;basename&nbsp;/usr/local/share/doc/foo/foo.txt<br>foo.txt<br>$&nbsp;basename&nbsp;/usr/home/drobbins<br>drobbins<br>Basename&nbsp;是一个截断字符串的极简便工具。它的相关命令&nbsp;dirname&nbsp;返回&nbsp;basename&nbsp;丢弃的“另”一部分路径。<br>$&nbsp;dirname&nbsp;/usr/local/share/doc/foo/foo.txt<br>/usr/local/share/doc/foo<br>$&nbsp;dirname&nbsp;/usr/home/drobbins/<br>/usr/home<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>命令替换<br>需要知道一个简便操作：如何创建一个包含可执行命令结果的环境变量。这很容易：<br>$&nbsp;MYDIR=`dirname&nbsp;/usr/local/share/doc/foo/foo.txt`<br>$&nbsp;echo&nbsp;$MYDIR<br>/usr/local/share/doc/foo<br>上面所做的称为“命令替换”。此例中有几点需要指出。在第一行，简单地将要执行的命令以&nbsp;<em>反引号</em>&nbsp;括起。那不是标准的单引号，而是键盘中通常位于&nbsp;Tab&nbsp;键之上的单引号。可以用&nbsp;bash&nbsp;备用命令替换语法来做同样的事：&nbsp;<br>$&nbsp;MYDIR=$(dirname&nbsp;/usr/local/share/doc/foo/foo.txt)<br>$&nbsp;echo&nbsp;$MYDIR<br>/usr/local/share/doc/foo<br>如您所见，bash&nbsp;提供多种方法来执行完全一样的操作。使用命令替换可以将任何命令或命令管道放在&nbsp;`&nbsp;`&nbsp;或&nbsp;$(&nbsp;)&nbsp;之间，并将其分配给环境变量。真方便！下面是一个例子，演示如何在命令替换中使用管道：<br>MYFILES=$(ls&nbsp;/etc&nbsp;|&nbsp;grep&nbsp;pa)<br>bash-2.03$&nbsp;echo&nbsp;$MYFILES<br>pam.d&nbsp;passwd<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>象专业人员那样截断字符串<br>尽管&nbsp;basename&nbsp;和&nbsp;dirname&nbsp;是很好的工具，但有时可能需要执行更高级的字符串“截断”，而不只是标准的路径名操作。当需要更强的说服力时，可以利用&nbsp;bash&nbsp;内置的变量扩展功能。已经使用了类似于&nbsp;${MYVAR}&nbsp;的标准类型的变量扩展。但是&nbsp;bash&nbsp;自身也可以执行一些便利的字符串截断。看一下这些例子：<br>$&nbsp;MYVAR=foodforthought.jpg<br>$&nbsp;echo&nbsp;${MYVAR##*fo}<br>rthought.jpg<br>$&nbsp;echo&nbsp;${MYVAR#*fo}<br>odforthought.jpg<br>在第一个例子中，输入了&nbsp;${MYVAR##*fo}。它的确切含义是什么？基本上，在&nbsp;${&nbsp;}&nbsp;中输入环境变量名称，两个&nbsp;##，然后是通配符&nbsp;(&quot;*fo&quot;)。然后，bash&nbsp;取得&nbsp;MYVAR，找到从字符串&nbsp;&quot;foodforthought.jpg&quot;&nbsp;开始处开始、且匹配通配符&nbsp;&quot;*fo&quot;&nbsp;的&nbsp;<em>最长</em>&nbsp;子字符串，然后将其从字符串的开始处截去。刚开始理解时会有些困难，为了感受一下这个特殊的&nbsp;&quot;##&quot;&nbsp;选项如何工作，让我们一步步地看看&nbsp;bash&nbsp;如何完成这个扩展。首先，它从&nbsp;&quot;foodforthought.jpg&quot;&nbsp;的开始处搜索与&nbsp;&quot;*fo&quot;&nbsp;通配符匹配的子字符串。以下是检查到的子字符串：&nbsp;<br>f&nbsp;&nbsp;&nbsp;<br>fo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MATCHES&nbsp;*fo<br>foo&nbsp;<br>food<br>foodf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>foodfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MATCHES&nbsp;*fo<br>foodfor<br>foodfort&nbsp;&nbsp;&nbsp;&nbsp;<br>foodforth<br>foodfortho&nbsp;&nbsp;<br>foodforthou<br>foodforthoug<br>foodforthought<br>foodforthought.j<br>foodforthought.jp<br>foodforthought.jpg<br>在搜索了匹配的字符串之后，可以看到&nbsp;bash&nbsp;找到两个匹配。它选择最长的匹配，从初始字符串的开始处除去，然后返回结果。<br>上面所示的第二个变量扩展形式看起来与第一个相同，但是它只使用一个&nbsp;&quot;#&quot;&nbsp;--&nbsp;并且&nbsp;bash&nbsp;执行&nbsp;<em>几乎</em>&nbsp;同样的过程。它查看与第一个例子相同的子字符串系列，但是&nbsp;bash&nbsp;从初始字符串除去&nbsp;<em>最短</em>&nbsp;的匹配，然后返回结果。所以，一查到&nbsp;&quot;fo&quot;&nbsp;子字符串，它就从字符串中除去&nbsp;&quot;fo&quot;，然后返回&nbsp;&quot;odforthought.jpg&quot;。&nbsp;<br>这样说可能会令人十分困惑，下面以一简单方式记住这个功能。当搜索最长匹配时，使用&nbsp;##（因为&nbsp;##&nbsp;比&nbsp;#&nbsp;长）。当搜索最短匹配时，使用&nbsp;#。看，不难记吧！等一下，怎样记住应该使用&nbsp;&#39;#&#39;&nbsp;字符来从字符串开始部分除去？很简单！注意到了吗：在美国键盘上，shift-4&nbsp;是&nbsp;&quot;$&quot;，它是&nbsp;bash&nbsp;变量扩展字符。在键盘上，紧靠&nbsp;&quot;$&quot;&nbsp;左边的是&nbsp;&quot;#&quot;。这样，可以看到：&quot;#&quot;&nbsp;位于&nbsp;&quot;$&quot;&nbsp;的“开始处”，因此（根据我们的记忆法），&quot;#&quot;&nbsp;从字符串的开始处除去字符。您可能要问：如何从字符串末尾除去字符。如果猜到我们使用美国键盘上紧靠&nbsp;&quot;$&quot;&nbsp;<em>右边</em>&nbsp;的字符&nbsp;(&quot;%)，那就猜对了。这里有一些简单的例子，解释如何截去字符串的末尾部分：&nbsp;<br>$&nbsp;MYFOO=&quot;chickensoup.tar.gz&quot;<br>$&nbsp;echo&nbsp;${MYFOO%%.*}<br>chickensoup<br>$&nbsp;echo&nbsp;${MYFOO%.*}<br>chickensoup.tar<br>正如您所见，除了将匹配通配符从字符串末尾除去之外，%&nbsp;和&nbsp;%%&nbsp;变量扩展选项与&nbsp;#&nbsp;和&nbsp;##&nbsp;的工作方式相同。请注意：如果要从末尾除去特定子字符串，不必使用&nbsp;&quot;*&quot;&nbsp;字符：<br>MYFOOD=&quot;chickensoup&quot;<br>$&nbsp;echo&nbsp;${MYFOOD%%soup}<br>chicken<br>在此例中，使用&nbsp;&quot;%%&quot;&nbsp;或&nbsp;&quot;%&quot;&nbsp;并不重要，因为只能有一个匹配。还要记住：如果忘记了应该使用&nbsp;&quot;#&quot;&nbsp;还是&nbsp;&quot;%&quot;，则看一下键盘上的&nbsp;3、4&nbsp;和&nbsp;5&nbsp;键，然后猜出来。<br>可以根据特定字符偏移和长度，使用另一种形式的变量扩展，来选择特定子字符串。试着在&nbsp;bash&nbsp;中输入以下行：<br>$&nbsp;EXCLAIM=cowabunga<br>$&nbsp;echo&nbsp;${EXCLAIM:0:3}<br>cow<br>$&nbsp;echo&nbsp;${EXCLAIM:3:7}<br>abunga<br>这种形式的字符串截断非常简便，只需用冒号分开来指定起始字符和子字符串长度。<br><img src="attachments/m&#111;nth_0811/2008112012102716390_0.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_1.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><img src="attachments/m&#111;nth_0811/2008112012102716390_3.jpg" border="0" onload="javascript:DrawImage(this);"  alt="按此在新窗口打开图片" onmouseover="this.style.cursor='hand';" onclick="window.open(this.src);" /><br><a target="_blank" href="http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/#main"><strong><font color="#5c81a7">回页首</font></strong></a><br>应用字符串截断<br>现在我们已经学习了所有截断字符串的知识，下面写一个简单短小的&nbsp;shell&nbsp;脚本。我们的脚本将接受一个文件作为自变量，然后打印：该文件是否是一个&nbsp;tar&nbsp;文件。要确定它是否是&nbsp;tar&nbsp;文件，将在文件末尾查找模式&nbsp;&quot;.tar&quot;。如下所示：<br><strong>mytar.sh&nbsp;--&nbsp;一个简单的脚本</strong><br>#!/bin/bash<br>if&nbsp;[&nbsp;&quot;${1##*.}&quot;&nbsp;=&nbsp;&quot;tar&quot;&nbsp;]<br>then&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;This&nbsp;appears&nbsp;to&nbsp;be&nbsp;a&nbsp;tarball.<br>else<br>&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;At&nbsp;first&nbsp;glance,&nbsp;this&nbsp;does&nbsp;not&nbsp;appear&nbsp;to&nbsp;be&nbsp;a&nbsp;tarball.<br>fi<br>要运行此脚本，将它输入到文件&nbsp;mytar.sh&nbsp;中，然后输入&nbsp;&quot;chmod&nbsp;755&nbsp;mytar.sh&quot;，生成可执行文件。然后，如下做一下&nbsp;tar&nbsp;文件试验：<br>$&nbsp;./mytar.sh&nbsp;thisfile.tar<br>This&nbsp;appears&nbsp;to&nbsp;be&nbsp;a&nbsp;tarball.<br>$&nbsp;./mytar.sh&nbsp;thatfile.gz<br>At&nbsp;first&nbsp;glance,&nbsp;this&nbsp;does&nbsp;not&nbsp;appear&nbsp;to&nbsp;be&nbsp;a&nbsp;tarball.<br>好，成功运行，但是不太实用。在使它更实用之前，先看一下上面使用的&nbsp;&quot;if&quot;&nbsp;语句。语句中使用了一个布尔表达式。在&nbsp;bash&nbsp;中，&quot;=&quot;&nbsp;比较运算符检查字符串是否相等。在&nbsp;bash&nbsp;中，所有布尔表达式都用方括号括起。但是布尔表达式实际上测试什么？让我们看一下左边。根据前面所学的字符串截断知识，&quot;${1##*.}&quot;&nbsp;将从环境变量&nbsp;&quot;1&quot;&nbsp;包含的字符串开