1 |
r0bertz 07/10/06 17:32:16 |
2 |
|
3 |
Added: bash-by-example-p1.xml |
4 |
Log: |
5 |
added doc/zh_cn/articles/bash-by-example-p1.xml |
6 |
|
7 |
Revision Changes Path |
8 |
1.1 xml/htdocs/doc/zh_cn/articles/bash-by-example-p1.xml |
9 |
|
10 |
file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/zh_cn/articles/bash-by-example-p1.xml?rev=1.1&view=markup |
11 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/zh_cn/articles/bash-by-example-p1.xml?rev=1.1&content-type=text/plain |
12 |
|
13 |
Index: bash-by-example-p1.xml |
14 |
=================================================================== |
15 |
<?xml version='1.0' encoding="UTF-8"?> |
16 |
|
17 |
<!-- $Header --> |
18 |
<!-- English CVS version 1.7 --> |
19 |
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd"> |
20 |
|
21 |
<guide link="/doc/zh_cn/articles/bash-by-example-p1.xml" disclaimer="articles" lang="zh_cn"> |
22 |
<title>Bash示例,第一部分</title> |
23 |
|
24 |
<author title="作者"> |
25 |
<mail link="drobbins@g.o">Daniel Robbins</mail> |
26 |
</author> |
27 |
<author title="译者"> |
28 |
<mail link="night2008@×××××.com">苏永恒</mail> |
29 |
</author> |
30 |
<abstract> |
31 |
通过学习如何运用bash脚本语言进行编程,你每天和linux的交互将变的更有意思和有生产力,同时你也将能够构建那些你所知和喜欢的标准UNIX概念(诸如管道和重定向)。在这三部分的系列中,Daniel Robbins将教你如何通过bash例程进行编程。他将讲述非常基本的内容(这使它成为入门者优秀的系列)并在后续的系列中引入更加高级的特征。 |
32 |
</abstract> |
33 |
|
34 |
<!-- The original version of this article was published on IBM developerWorks, |
35 |
and is property of Westtech Information Services. This document is an updated |
36 |
version of the original article, and contains various improvements made by the |
37 |
Gentoo Linux Documentation team --> |
38 |
<version>1.3</version> |
39 |
<date>2005-10-09</date> |
40 |
|
41 |
<chapter> |
42 |
<title>Bourne again shell(bash)基础编程</title> |
43 |
<section> |
44 |
<title>简介</title> |
45 |
<body> |
46 |
|
47 |
<p> |
48 |
你可能会奇怪为什么你应该学习Bash编程。那么,这里有两个令人信服的理由: |
49 |
</p> |
50 |
|
51 |
</body> |
52 |
</section> |
53 |
<section> |
54 |
<title>你已经开始运行它了</title> |
55 |
<body> |
56 |
|
57 |
<p> |
58 |
如果检查一下,你可能将会发现你现在正在运行bash。即使你改变了你默认的shell,bash也可能仍在你系统的某个地方运行,因为它是标准的Linux shell并被用做多种用途。由于bash已经运行,你运行的任何附加的bash脚本拥有固有的内存高效性,这是因为它们和任何已经运行的bash进程共享内存。如果你已经运行了些东西来做这项工作,并且做的很好,那还为什么要载入一个500K的解释器呢? |
59 |
</p> |
60 |
|
61 |
</body> |
62 |
</section> |
63 |
<section> |
64 |
<title>你正在使用它</title> |
65 |
<body> |
66 |
|
67 |
<p> |
68 |
不仅是因为你已经运行了bash,另外你还在每天的基本工作中与bash进行交互。它就在那里,所以学习如何最大限度的使用它就变得很有意义。这么做将是你的bash之旅更加有意思和具有创制性。但是为什么你应该学习bash编程呢?很简单,因为你已经在思考运行命令,复制粘贴文件,以及管道和重定向输出。那你是否应该学习这种语言,以便使用和利用那些已熟悉和喜爱的强大省时的概念呢?命令shell开启了UNIX系统的潜能,而bash就是Linux shell。它是你和机器之间的高等级的纽带。随着你的bash知识的增长,同时你将能自动的增加你在Linux和UNIX下的生产力──就是这么简单。 |
69 |
</p> |
70 |
|
71 |
</body> |
72 |
</section> |
73 |
<section> |
74 |
<title>Bash的困惑</title> |
75 |
<body> |
76 |
|
77 |
<p> |
78 |
通过错误的方法学习bash会是一个非常困惑的过程。很多新手敲入<c>man bash</c>来查看bash的man页,但令人头疼的是只面临一些shell函数特别简明和科技性的解释。其他人通过敲入<c>info bash</c>(来查看GNU的信息文档),但可能是man页的翻版,也可能(如果他们幸运的话)仅是一些稍微友好的信息文档出现。 |
79 |
</p> |
80 |
|
81 |
<p> |
82 |
然而这些对于初学者来说在一定程度上是令人沮丧的,标准的bash文档不可能是适合于每一个人的所有东西和迎合所有已经对一般的shell编程十分熟悉的人。毋庸置疑的,在man页上有很多优秀的技术性的信息,但是它对于初学者来说帮助是有限的。 |
83 |
</p> |
84 |
|
85 |
<p> |
86 |
这是这个系列存在的原因。在它里面,我将向你展示如何有效的使用bash编程结构,以便你能够编写你自己的脚本。与科技性的说明不同的是,我将通过易懂的英文向你们讲解,使你不仅知道这是什么,而且知道你应该在什么时候有效的使用它。到这个三部分的系列之后,你将能够编写你自己的精巧的bash脚本,并能够达到一个能够很舒服的使用bash和通过读(和理解)标准的bash文档来增进你的知识的层次上。那就让我们开始吧! |
87 |
</p> |
88 |
|
89 |
</body> |
90 |
</section> |
91 |
<section> |
92 |
<title>环境变量</title> |
93 |
<body> |
94 |
|
95 |
<p> |
96 |
在bash和几乎所有其他shell下,用户可以定义环境变量,它们被以ASCII字符的形式存储在内部。环境变量最有用的地方在于它们是UNIX作业模型中的一个标准部分。这意味着环境变量并非是shell脚本所独有,而是同样可以为标准的编译程序所使用。当我们在bash下"export"一个环境变量,任何之后我们运行的程序都可以读取我们的设定,而不管它是否是不是一个shell脚本。一个很好的例子是<c>vipw</c>命令,它通常允许root去编辑系统密码文件。通过设定<c>EDITER</c>环境变量来命名你喜欢的文本编辑器,你可以设定vipw去使用而不是vi,特别是如果你习惯于xemacs而又实在讨厌vi。 |
97 |
</p> |
98 |
|
99 |
<p> |
100 |
在bash下定义一个环境变量的标准方法是: |
101 |
</p> |
102 |
|
103 |
<pre caption="定义环境变量"> |
104 |
$ <i>myvar='This is my environment variable!'</i> |
105 |
</pre> |
106 |
|
107 |
<p> |
108 |
上面的命令定义了一个叫"myvar"的环境变量并包含"This is my environment variable!"字符串。上面有很多是需要我们注意的:首先,在"="号两侧没有空格,任何空格都将导致一个错误产生(可以试一下看看)。第二要注意的是虽然在定义一个词时我们可以省略引号,但当环境变量的值多于一个词(包含空格或制表符)时,引号却是必须的。 |
109 |
</p> |
110 |
|
111 |
<note> |
112 |
要想获得关于如何在bash中使用引号的更加详尽的信息,请参考bash man页中"QUOTING"一节。特殊字符序列由其它值"扩展"(替换)确实使 bash 中字符串的处理变得复杂。本系列将只讲述最常用的引用功能。 |
113 |
</note> |
114 |
|
115 |
<p> |
116 |
第三,当我们通常可以用双引号代替单引号,在上面的例子中这样做会导致一个错误。为什么呢?因为用单引号禁用了一个bash称为扩展的特性,其中特殊字符和字符序列的值可以互换。比如,"!"字符是历史扩展字符,它通常由之前敲入的命令所替换。(在这个系列的文章中,我们不能讲述历史扩展,那是在我们bash编程中不常用到它。要获得相关的更多信息,请看bash man页中的"HISTORY EXPANSION"部分。)尽管这个类似于宏的功能很便利,但我们现在只想在环境变量后面加上一个简单的感叹号,而不是宏。 |
117 |
</p> |
118 |
|
119 |
<p> |
120 |
现在让我们看一下一个人如何运用环境变量。下面是例子: |
121 |
</p> |
122 |
|
123 |
<pre caption="运用环境变量"> |
124 |
$ <i>echo $myvar</i> |
125 |
This is my environment variable! |
126 |
</pre> |
127 |
|
128 |
<p> |
129 |
通过在我们的环境变量前加上一个$,我们可以使bash来用myvar的值来取代它。在bash的术语中,这被成为"变量扩展"。但是,如果我们试过下面的会怎样: |
130 |
</p> |
131 |
|
132 |
<pre caption="首先使用变量扩展"> |
133 |
$ <i>echo foo$myvarbar</i> |
134 |
foo |
135 |
</pre> |
136 |
|
137 |
<p> |
138 |
我们希望这能echo "fooThis is my environment variable!bar",但是它却没有起作用。哪里出错了呢?简单的说,bash的变量扩展很容易让人迷惑。它不能判别我们要扩展的变量是$m,$my,$myvar,$myvarbar等等。我们如何才能明确的清楚的告诉bash我们提到的是哪个变量呢?请试一下这个: |
139 |
</p> |
140 |
|
141 |
<pre caption="合适的变量扩展"> |
142 |
$ <i>echo foo${myvar}bar</i> |
143 |
fooThis is my environment variable!bar |
144 |
</pre> |
145 |
|
146 |
<p> |
147 |
你可以看到,当环境变量名没有很清晰的和周围的文本分开时,我们可以把它们放在一对括号内。然而$myvar可以很快的打出来并在大部分时候都能工作,${myvar}在几乎所有的情况下都能正确的解析出来。除此之外,它们都做同样的事情,在以下的这个系列中这两种形式的变量扩展你将都能看到。当你的环境变量没有和你周围的文本用空白(空格或制表符)分开时,你将希望记住使用更加复杂的带括号的形式。 |
148 |
</p> |
149 |
|
150 |
<p> |
151 |
还记的我们还提到过我们可以"导出"变量。当我们导出一个环境变量时,它将自动的可以在任何随后执行或可执行的脚本中使用。Shell脚本可以运用shell的内建环境变量支持"获取"环境变量,而C程序可以运用getenv()函数来调用。这里是一些你应该敲入并编译的C代码的例子──它都可以使我们从C的视角来理解环境变量: |
152 |
</p> |
153 |
|
154 |
<pre caption="myvar.c──一个C程序环境变量的例子"> |
155 |
#include <stdio.h> |
156 |
#include <stdlib.h> |
157 |
|
158 |
int main(void) { |
159 |
char *myenvvar=getenv("EDITOR"); |
160 |
printf("The editor environment variable is set to %s\n",myenvvar); |
161 |
} |
162 |
</pre> |
163 |
|
164 |
<p> |
165 |
保存上面的源代码到一个叫<path>myenv.c</path>的文件,然后通过发出下面指令编译它: |
166 |
</p> |
167 |
|
168 |
<pre caption="编译上面的源代码"> |
169 |
$ <i>gcc myenv.c -o myenv</i> |
170 |
</pre> |
171 |
|
172 |
<p> |
173 |
现在在你的文件夹里将有一个可执行的程序,当你运行它时,如果有,将打印出<c>EDITOR</c>的环境变量值。这是当我在我的机器上运行它时的结果: |
174 |
</p> |
175 |
|
176 |
<pre caption="运行上面的程序"> |
177 |
$ <i>./myenv</i> |
178 |
The editor environment variable is set to (null) |
179 |
</pre> |
180 |
|
181 |
<p> |
182 |
Hmmm...因为环境变量<c>EDITOR</c>没有设定任何值,C程序得到的是一个空字符串。让我们试着将它设为一个特定的值: |
183 |
</p> |
184 |
|
185 |
<pre caption="用特定的值试验"> |
186 |
$ <i>EDITOR=xemacs</i> |
187 |
$ <i>./myenv</i> |
188 |
编辑器的环境变量被设为(空) |
189 |
</pre> |
190 |
|
191 |
<p> |
192 |
然而你可能会希望myenv会打印值"xemacs",它并非很管用,因为我们没有export<c>EDITOR</c>环境变量。这次,我们将让它起作用: |
193 |
</p> |
194 |
|
195 |
<pre caption="同样的程序在导出变量后"> |
196 |
$ <i>export EDITOR</i> |
197 |
$ <i>./myenv</i> |
198 |
编辑器的环境变量被设为xemacs |
199 |
</pre> |
200 |
|
201 |
<p> |
202 |
因此,你已经用自己的眼睛看到另外一种方法(正如我们的C程序例子)直到环境变量被导出才能看到它。顺便一提,如果你喜欢,你可以用一行定义和输出一个环境变量,就像下面一样: |
203 |
</p> |
204 |
|
205 |
<pre caption="用一个命令定义和导出环境变量"> |
206 |
$ <i>export EDITOR=xemacs</i> |
207 |
</pre> |
208 |
|
209 |
<p> |
210 |
它的工作和两行的版本是一样的。这是一个好的时机去展示如何用<c>unset</c>去除一个环境变量。 |
211 |
</p> |
212 |
|
213 |
<pre caption="去除变量"> |
214 |
$ <i>unset EDITOR</i> |
215 |
$ <i>./myenv</i> |
216 |
|
217 |
</pre> |
218 |
|
219 |
</body> |
220 |
</section> |
221 |
<section> |
222 |
<title>拆分字符串综述</title> |
223 |
<body> |
224 |
|
225 |
<p> |
226 |
拆分字符串──它是将原始字符串拆分成小一点的,切片──是一个在你平常每天的shell脚本执行中的任务。很多时候,shell脚本需要采用全限定路径,并找到结束的文件或目录。虽然可以用bash编码实现(而且有趣),但标准<c>basename</c> UNIX可执行程序可以极好地完成此工作: |
227 |
</p> |
228 |
|
229 |
<pre caption="运用basename"> |
230 |
$ <i>basename /usr/local/share/doc/foo/foo.txt</i> |
231 |
foo.txt |
232 |
$ <i>basename /usr/home/drobbins</i> |
233 |
drobbins |
234 |
</pre> |
235 |
|
236 |
<p> |
237 |
<c>basename</c>是一个拆分字符串的及其简便的工具。与它相关的被称为<c>dirname</c>返回<c>basename</c>丢弃的"另"一部分路径。 |
238 |
</p> |
239 |
|
240 |
<pre caption="运用dirname"> |
241 |
$ <i>dirname /usr/local/share/doc/foo/foo.txt</i> |
242 |
/usr/local/share/doc/foo |
243 |
$ <i>dirname /usr/home/drobbins/</i> |
244 |
/usr/home |
245 |
</pre> |
246 |
|
247 |
<note> |
248 |
<c>dirname</c>和<c>basename</c>都不考虑磁盘上的任何文件和文件夹;它们是纯粹的字符串操作命令。 |
249 |
</note> |
250 |
|
251 |
</body> |
252 |
</section> |
253 |
<section> |
254 |
<title>命令替换</title> |
255 |
<body> |
256 |
|
257 |
<p> |
258 |
需要知道一个很简便的操作,如何创建一个包含可执行命令结果的环境变量。这是很容易做的: |
259 |
</p> |
260 |
|
261 |
<pre caption="创建一个包含命令结果的环境变量"> |
262 |
$ <i>MYDIR=`dirname /usr/local/share/doc/foo/foo.txt`</i> |
263 |
$ <i>echo $MYDIR</i> |
264 |
/usr/local/share/doc/foo |
265 |
</pre> |
266 |
|
267 |
<p> |
268 |
我们上面所做的被称为<e>命令替换</e>。在这个例子中有很多值得注意的。在第一行,我们简单的将命令用反引号括起。这些不是标准的单引号,而是通常在键盘上位于Tab键之上的单引号。我们用bash的交互命令语法来做同样的事情: |
269 |
</p> |
270 |
|
271 |
<pre caption="交互命令替换语法"> |
272 |
$ <i>MYDIR=$(dirname /usr/local/share/doc/foo/foo.txt)</i> |
273 |
$ <i>echo $MYDIR</i> |
274 |
/usr/local/share/doc/foo |
275 |
</pre> |
276 |
|
277 |
<p> |
278 |
正如我们所见,bash提供了很多执行相同操作的方法。运用命令替换,我们可以将任何命令和命令管道放在<e>` `</e>或<e>$( )</e>之间并把它指定为环境变量。多方便啊!这里是一个如何在命令替换中使用管道的例子: |
279 |
</p> |
280 |
|
281 |
<pre caption="管道命令替换"> |
282 |
$ <i>MYFILES=$(ls /etc/| grep pa)</i> |
283 |
$ <i>echo $MYFILES</i> |
284 |
pam.d passwd |
285 |
</pre> |
286 |
|
287 |
</body> |
288 |
</section> |
289 |
<section> |
290 |
<title>像个专家一样拆分字符串</title> |
291 |
<body> |
292 |
|
293 |
<p> |
294 |
尽管<c>basename</c>和<c>dirname</c>是很棒的工具,但我们可能时常需要更加专业的字符串"拆分"操作而不是仅仅的标准的路径名处理。当我们需要更强的说服力时,我们可以利用bash内建的变量扩展功能。我们已经使用了标准的变量扩展,就像:${MYVAR}。但是bash还可以自己执行一些便利的字符串拆分。请看一下这些例子: |
295 |
</p> |
296 |
|
297 |
<pre caption="字符串拆分示例"> |
298 |
$ <i>MYVAR=foodforthought.jpg</i> |
299 |
$ <i>echo ${MYVAR##*fo}</i> |
300 |
rthought.jpg |
301 |
$ <i>echo ${MYVAR#*fo}</i> |
302 |
odforthought.jpg |
303 |
</pre> |
304 |
|
305 |
<p> |
306 |
在第一个例子中,我们敲入${MYVAR##*fo}。那么它确切的意思是什么呢?基本上,在${ }中,我们敲入环境变量的名字,两个##和一个通配符("*fo")。然后,bash获取<c>MYVAR</c>,从字符串"foodforthought.jpg"的起始处查找匹配通配符"*fo"的最长的子串并将其从字符串的开始处拆分。刚开始这有一点难以掌握,为了感受一下这个特殊的"##"选项是如何工作的,让我们一步步探讨bash是如何完成这个扩展的。首先,它从"foodforthought.jpg的开始处开始搜索匹配"*fo"通配符的子串。这里是它检查到的子串: |
307 |
</p> |
308 |
|
309 |
<pre caption="子串检查"> |
310 |
f |
311 |
fo MATCHES *fo |
312 |
foo |
313 |
food |
314 |
foodf |
315 |
foodfo MATCHES *fo |
316 |
foodfor |
317 |
foodfort |
318 |
foodforth |
319 |
foodfortho |
320 |
foodforthou |
321 |
foodforthoug |
322 |
foodforthought |
323 |
foodforthought.j |
324 |
foodforthought.jp |
325 |
foodforthought.jpg |
326 |
</pre> |
327 |
|
328 |
<p> |
329 |
寻找到匹配的字符串后,你可以看到bash找到两个。它选择了最长匹配,从原始字符串的开始处出去,然后返回结果。 |
330 |
</p> |
331 |
|
332 |
<p> |
333 |
上面的第二种形式的变量扩展和第一种表现的完全相同,只是它只运用一个"#"──并且bash执行了一个几乎相同的过程。正如我们的第一个例子一样,它检查乐同样的一些子串,除了bash从我们的原始字符串中移除了最短匹配并返回结果。所以,它一检查到"fo"子串,它就从我们的字符串中移除"fo"并返回"odforthought.jpg"。 |
334 |
</p> |
335 |
|
336 |
<p> |
337 |
这看起来很神秘,所以我们将向你展示一个简单的方法去记住这个功能。当搜索最长匹配时,运用##(因为##比#要长)。当搜索最短匹配时,用#。看,也并不是那么难去记忆!等等,怎样记住应该使用'#'字符来从字符串起始处移除呢?很简单!注意一下在US键盘上,shift-4是"$",它是bash变量扩展字符。在键盘上,紧靠在"$"左边是"#"。所以,你可以看到"#"是在"$"的"起始处的",因此(根据我们的记忆法),"#"从字符串的起始处移除字符。你可能还想知道如何从字符串的末尾移除字符。如果猜到我们用的字符是US键盘上紧靠在"$"右边的"%",正确!这里有几个简单的例子来解释如何拆分字符串的末尾部分: |
338 |
</p> |
339 |
|
340 |
<pre caption=""> |
341 |
$ <i>MYFOO="chickensoup.tar.gz"</i> |
342 |
$ <i>echo ${MYFOO%%.*}</i> |
343 |
chickensoup |
344 |
$ <i>echo ${MYFOO%.*}</i> |
345 |
chickensoup.tar |
346 |
</pre> |
347 |
|
348 |
<p> |
349 |
正如你所见,除了将匹配通配符从字符串末尾去除之外,%和%%变量扩展的选项和#和##没有什么不同。注意:如果你希望从末尾移除一个特殊的子串,则不能运用"*"字符: |
350 |
</p> |
351 |
|
352 |
<pre caption="从末尾移去字符"> |
353 |
<i>MYFOOD="chickensoup"</i> |
354 |
$ <i>echo ${MYFOOD%%soup}</i> |
355 |
chicken |
356 |
</pre> |
357 |
|
358 |
<p> |
359 |
在这个例子中,既然只有一个匹配,我们使用"%%"或"%"也就不重要了。同时记住,如果你忘记了是使用"#"还是"%",请看键盘上的3,4,5键并猜出来。 |
360 |
</p> |
361 |
|
362 |
<p> |
363 |
我们可以运用其它形式的变量扩展来选择一个特殊的子串,它是基于一个特定的字符串偏移和长度。请尝试在bash下敲入下面几行: |
364 |
</p> |
365 |
|
366 |
<pre caption="选择一个特殊的子字符串"> |
367 |
$ <i>EXCLAIM=cowabunga</i> |
368 |
$ <i>echo ${EXCLAIM:0:3}</i> |
369 |
cow |
370 |
$ <i>echo ${EXCLAIM:3:7}</i> |
371 |
abunga |
372 |
</pre> |
373 |
|
374 |
<p> |
375 |
这种形式的字符串拆分将十分简便;只需简单的用冒号分开指定字符的起始字符和子串的长度。 |
376 |
</p> |
377 |
|
378 |
</body> |
379 |
</section> |
380 |
<section> |
381 |
<title>应用字符串拆分</title> |
382 |
<body> |
383 |
|
384 |
<p> |
385 |
现在我们已经学了拆分字符串的所有内容,让我们写一个简单的小shell脚本。我们的脚本将接受单个文件作为参数并打印出它是否是一个压缩档,它将在文件的结尾寻找模式".tar"。下面就是: |
386 |
</p> |
387 |
|
388 |
<pre caption="mytar.sh──一个示例脚本"> |
389 |
#!/bin/bash |
390 |
|
391 |
if [ "${1##*.}" = "tar" ] |
392 |
then |
393 |
echo This appears to be a tarball. |
394 |
else |
395 |
echo At first glance, this does not appear to be a tarball. |
396 |
fi |
397 |
</pre> |
398 |
|
399 |
<p> |
400 |
要运行这个脚本,将它输入到几个叫<path>mytar.sh</path>,并敲入<c>chmod 755 mytar.sh</c>使它可执行。然后如下给他一个压缩档做试验: |
401 |
</p> |
402 |
|
403 |
<pre caption="尝试这个脚本"> |
404 |
$ <i>./mytar.sh thisfile.tar</i> |
405 |
This appears to be a tarball. |
406 |
$ <i>./mytar.sh thatfile.gz</i> |
407 |
At first glance, this does not appear to be a tarball. |
408 |
</pre> |
409 |
|
410 |
<p> |
411 |
好,它工作了,但是它不是很实用。在我们将它变得实用之前,先让我们看看上面用的"if"语句。其中,我们有一个布尔表达式。在bash中,"="比较操作检查字符串是否相等。但是这布尔表达式真正测试的是什么呢?让我们看看左边。通过我们所学习的字符串拆分,"${1##*.}"将从包含环境变量"1"的字符串起始处移除"*."的最长匹配,并返回结果。这将返回文件中最后一个"."之后的所有部分。很明显,如果一个文件以".tar"结尾,我们将获取"tar"作为结果,条件也就为真。 |
412 |
</p> |
413 |
|
414 |
<p> |
415 |
你可能会吃惊环境变量"1"是在第一个位置。非常简单──$1是这个脚本的第一个命令行参数,$2是第二个,如此等等。好的,现在我们已经回顾乐这个函数,我们可以看一下"if"语句了。 |
416 |
</p> |
417 |
|
418 |
</body> |
419 |
</section> |
420 |
<section> |
421 |
<title>If语句</title> |
422 |
<body> |
423 |
|
424 |
<p> |
425 |
像大多语言一样,bash有它自己的条件类型。当使用它们时,请准照上面的格式;它是使"if"和"then"在不同的行,"else"和结束处必须的"fi"和它们水平对齐。这使代码易于阅读和调试。除了"if,else"形式,"if"语句还有很多其它形式: |
426 |
</p> |
427 |
|
428 |
<pre caption="if语句的基本结构"> |
429 |
if [ condition ] |
430 |
then |
431 |
action |
432 |
fi |
433 |
</pre> |
434 |
|
435 |
<p> |
436 |
只有当condition为真的,它才会执行一个动作,否则它不执行任何动作并继续执行直到"fi"的行。 |
437 |
</p> |
438 |
|
439 |
<pre caption="在继续fi之后的命令之前检查状况"> |
440 |
if [ condition ] |
441 |
then |
442 |
action |
443 |
elif [ condition2 ] |
444 |
then |
445 |
action2 |
446 |
. |
447 |
. |
448 |
. |
449 |
elif [ condition3 ] |
450 |
then |
451 |
|
452 |
else |
453 |
actionx |
454 |
fi |
455 |
</pre> |
456 |
|
457 |
<p> |
458 |
上面的"elif"序列将连续测试每一个condition并执行第一个真的condition所相应的动作。如果没有condition是真,它将执行"else"动作,如果有一个为真,它将继续执行所有接下来的"if,elif,else"语句。 |
459 |
</p> |
460 |
|
461 |
</body> |
462 |
</section> |
463 |
<section> |
464 |
<title>下一次</title> |
465 |
<body> |
466 |
|
467 |
<p> |
468 |
现在我们已经涵盖了大部分的基本的bash功能,是时候加快脚步准备书写一些真正的脚本了。在下一部分中,我将讲述循环结构,函数,命名空间和其它重要的话题。接下来我们将准备写更多的复杂的脚本。在第三篇文章中,我们将重点集中在非常复杂的脚本和函数上,正如很多bash脚本设计选项一样。到时候再见! |
469 |
</p> |
470 |
|
471 |
</body> |
472 |
</section> |
473 |
</chapter> |
474 |
|
475 |
<chapter> |
476 |
<title>资源</title> |
477 |
<section> |
478 |
<title>有用的链接</title> |
479 |
<body> |
480 |
|
481 |
<ul> |
482 |
<li> |
483 |
请阅读<uri link="http://www.gentoo.org/doc/zh_cn/articles/bash-by-example-p2.xml">Bash示例:第二部分</uri> |
484 |
</li> |
485 |
<li> |
486 |
请阅读<uri link="http://www.gentoo.org/doc/zh_cn/articles/bash-by-example-p3.xml">Bash示例:第三部分</uri> |
487 |
</li> |
488 |
<li> |
489 |
访问<uri link="http://www.gnu.org/software/bash/bash.html">GUN's bash home page</uri> |
490 |
</li> |
491 |
</ul> |
492 |
|
493 |
</body> |
494 |
</section> |
495 |
</chapter> |
496 |
</guide> |
497 |
|
498 |
|
499 |
|
500 |
-- |
501 |
gentoo-commits@g.o mailing list |