快捷搜索:

Bourne again shell (bash) 基本编程

已经在运行它

假如查看一下,可能会发明:您现在正在运行 bash。由于 bash 是标准 Linux shell,并用于各类目的,以是,纵然变动了缺省 shell,bash 可能仍在系统中某处运行。由于 bash 已在运行,今后运行的任何 bash 脚本都生成是有效使用内存的,由于它们与任何已运行的 bash 进程共享内存。假如正在运行的对象可以胜任事情,并且做得很好,为什么还要装入一个 500K 的说冥器?

已经在应用它

不仅在运行 bash,实际上,您天天还在与 bash 打交道。它总在那里,是以进修若何最大年夜限度应用它是故意义的。这样做将使您的 bash 履历更有趣和有临盆力。然则为什么要进修 bash 编程?很简单,由于您已在斟酌若何运行敕令、CPing 文件以及管道化和重定向输出。为什么不进修一种说话,以便应用和使用那些已认识和喜好的强大年夜省时的观点?敕令 shell 开启了 UNIX 系统的潜能,而 bash 恰是这个 Linux shell。它是您和机械之间的高档纽带。增长 bash 常识吧,这将自动前进您在 Linux 和 UNIX 中的临盆力 -- 就那么简单。

Bash 利诱

以差错要领进修 bash 令人十分利诱。许多新手输入 "man bash" 来查看 bash 赞助页,但只获得异常简单和技巧方面的 shell 功能性描述。还有人输入 "info bash"(来查看 GNU 信息文档),只能获得从新显示的赞助页,或者(假如幸运)略为友好的信息文档。

只管这可能使初学者有些失望,但标准 bash 文档无法满意所有人的要求,它只得当那些已大年夜体认识 shell 编程的人。赞助页中确凿有很多极好的技巧信息,但对初学者的赞助却有限。

这便是本系列的目的所在。在本系列中,我将讲述若何实际应用 bash 编程观点,以便编写自己的脚本。与技巧描述不合,我将以简单的说话为您解释,使您不仅知道工作做什么,还知道应在何时应用。在此三部分系列末端,您将可以自己编写繁杂的 bash 脚本,并可以自若地应用 bash 以及经由过程涉猎(和理解)标准 bash 文档来弥补常识。让我们开始吧。

情况变量

在 bash 和险些所有其它 shell 中,用户可以定义情况变量,这些情况变量在以 ASCII 字符串存储。情况变量的最便利之处在于:它们是 UNIX 进程模型的标准部分。这意味着:情况变量不仅由 shell 脚本独用,而且还可以由编译过的标准法度榜样应用。当在 bash 中“导出”情况变量时,今后运行的任何法度榜样,不管是不是 shell 脚本,都可以读取设置。一个很好的例子是 vipw 敕令,它平日容许 root 用户编辑系统口令文件。经由过程将 EDITOR 情况变量设置成喜好的文本编辑器名称,可以设置设置设备摆设摆设 vipw,使其应用该编辑器,而不应用 vi,假如习气于 xemacs 而确凿不爱好 vi,那么这是很便利的。

在 bash 中定义情况变量的标准措施是:

$ myvar='This is my environment variable!'

以上敕令定义了一个名为 "myvar" 的情况变量,并包孕字符串 "This is my environment variable!"。以上有几点留意事变:第一,在等号 "=" 的两边没有空格,任何空格将导致差错(试一下看看)。第二个件要留意的事是:虽然在定义一个字时可以省略引号,然则当定义的情况变量值多于一个字时(包孕空格或制表键),引号是必须的。

引用细节

有关若何在 bash 中应用引号的异常详尽的信息,请参阅 bash 赞助页面中的“引用”一节。特殊字符序列由其它值“扩展”(调换)确凿使 bash 中字符串的处置惩罚变得繁杂。本系列将只讲述最常用的引用功能。

第三,虽然平日可以用双引号来替代单引号,但在上例中,这样做会导致差错。为什么呢?由于应用单引号禁用了称为扩展的 bash 特点,此中,特殊字符和字符系列由值调换。例如,"!" 字符是历史扩展字符,bash 平日将其调换为前面输入的敕令。(本系列文章中将不讲述历史扩展,由于它在 bash 编程中不常用。有关历史扩展的具体信息,请参阅 bash 赞助页中的“历史扩展”一节。)只管这个类似于宏的功能很便利,但我们现在只想在情况变量后面加上一个简单的感叹号,而不是宏。

现在,让我们看一下若何实际应用情况变量。这有一个例子:

$ echo $myvar

This is my environment variable!

经由过程在情况变量的前面加上一个 $,可以使 bash 用 myvar 的值调换它。这在 bash 术语中叫做“变量扩展”。然则,这样做将如何:

$ echo foo$myvarbar

foo

我们盼望回显 "fooThis is my environment variable!bar",但却不是这样。错在哪里?简单地说,bash 变量扩展举措措施陷入了利诱。它无法识别要扩展哪一个变量:$m、$my、$myvar 、$myvarbar 等等。若何更明确清楚地告述 bash 引用哪一个变量?试一下这个:

$ echo foo${myvar}bar

fooThis is my environment variable!bar

如您所见,当情况变量没有与周围文本显着分开时,可以用花括号将它括起。虽然 $myvar 可以更快输入,并且在大年夜多半环境下精确事情,但 ${myvar} 却能在险些所有环境下精确经由过程语法阐发。除此之外,二者相同,将在本系列的余下部分看到变量扩展的两种形式。请记着:当情况变量没有用空缺(空格或制表键)与周围文本分开时,请应用更明确的花括号形式。

回顾一下,我们还提到过可以“导出”变量。当导出情况变量时,它可以自动地由今后运行的任何脚本或可履行法度榜样情况应用。shell 脚本可以应用 shell 的内置情况变量支持“到达”情况变量,而 C 法度榜样可以应用 getenv() 函数调用。这里有一些 C 代码示例,输入并编译它们 -- 它将赞助我们从 C 的角度理解情况变量:

myvar.c -- 样本情况变量 C 法度榜样

#include

#include

int main(void) {

char *myenvvar=getenv("EDITOR");

printf("The editor environment variable is set to %s",myenvvar);

}

将上面的代码保存到文件 myenv.c 中,然后发出以下敕令进行编译:

$ gcc myenv.c -o myenv

现在,目录中将有一个可履行法度榜样,它在运行时将打印 EDITOR 情况变量的值(假如有值的话)。这是在我机械上运行时的环境:

$ ./myenv

The editor environment variable is set to (null)

啊... 由于没有将 EDITOR 情况变量设置成任何值,以是 C 法度榜样获得一个空字符串。让我们试着将它设置成特定值:

$ EDITOR=xemacs

$ ./myenv

The editor environment variable is set to (null)

虽然盼望 myenv 打印值 "xemacs",然则由于还没有导出情况变量,以是它却没有很好地事情。此次让它精确事情:

$ export EDITOR

$ ./myenv

The editor environment variable is set to xemacs

现在,如您亲眼所见:不导出情况变量,另一个进程(在本例中是示例 C 法度榜样)就看不到情况变量。顺便提一句,假如乐意,可以在一行定义并导出情况变量,如下所示:

$ export EDITOR=xemacs

这与两行版本的效果相同。现在该演示若何应用 unset 来撤除情况变量:

$ unset EDITOR

$ ./myenv

The editor environment variable is set to (null)

dirname 和 basename

请留意:dirname 和 basename 不是磁盘上的文件或目录,它们只是字符串操作敕令。

截断字符串概述

截断字符串是将初始字符串截断成较小的自力块,它是一样平常 shell 脚本天天履行的义务之一。很多时刻,shell 脚本必要采纳全限制路径,并找到停止的文件或目录。虽然可以用 bash 编码实现(而且有趣),但标准 basename UNIX 可履行法度榜样可以极好地完成此事情:

$ basename /usr/local/share/doc/foo/foo.txt

foo.txt

$ basename /usr/home/drobbins

drobbins

Basename 是一个截断字符串的极简便对象。它的相关敕令 dirname 返回 basename 丢弃的“另”一部分路径。

$ dirname /usr/local/share/doc/foo/foo.txt

/usr/local/share/doc/foo

$ dirname /usr/home/drobbins/

/usr/home

敕令调换

必要知道一个简便操作:若何创建一个包孕可履行敕令结果的情况变量。这很轻易:

$ MYDIR=`dirname /usr/local/share/doc/foo/foo.txt`

$ echo $MYDIR

/usr/local/share/doc/foo

上面所做的称为“敕令调换”。此例中有几点必要指出。在第一行,简单地将要履行的敕令以 反引号括起。那不是标准的单引号,而是键盘中平日位于 Tab 键之上的单引号。可以用 bash 备用敕令调换语法来做同样的事:

$ MYDIR=$(dirname /usr/local/share/doc/foo/foo.txt)

$ echo $MYDIR

/usr/local/share/doc/foo

如您所见,bash 供给多种措施来履行完全一样的操作。应用敕令调换可以将任何敕令或敕令管道放在 ` ` 或 $( ) 之间,并将其分配给情况变量。真方便!下面是一个例子,演示若何在敕令调换中应用管道:

MYFILES=$(ls /etc | grep pa)

bash-2.03$ echo $MYFILES

pam.d passwd

象专业职员那样截断字符串

只管 basename 和 dirname 是很好的对象,但无意偶尔可能必要履行更高档的字符串“截断”,而不光是标准的路径名操作。当必要更强的说服力时,可以使用 bash 内置的变量扩展功能。已经应用了类似于 ${MYVAR} 的标

您可能还会对下面的文章感兴趣: