#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *myenvvar=getenv("EDITOR");
printf("The editor environment variable is set to %s\n",myenvvar); }
保存上面的源代码到一个叫myenv.c的文件,然后通过发出下面指令编译它:
(Gentoo)Bash示例,第一部分
代码 1.6: 编译上面的源代码
$ gcc myenv.c -o myenv
现在在你的文件夹里将有一个可执行的程序,当你运行它时,如果有,将打印出EDITOR的环境变量值。这是当我在我的机器上运行它时的结果: 代码 1.7: 运行上面的程序
$ ./myenv
The editor environment variable is set to (null)
Hmmm...因为环境变量EDITOR没有设定任何值,C程序得到的是一个空字符串。让我们试着将它设为一个特定的值: 代码 1.8: 用特定的值试验
$ EDITOR=xemacs
$ ./myenv
编辑器的环境变量被设为(空)
然而你可能会希望myenv会打印值"xemacs",它并非很管用,因为我们没有exportEDITOR环境变量。这次,我们将让它起作用: 代码 1.9: 同样的程序在导出变量后
$ export EDITOR
$ ./myenv
编辑器的环境变量被设为xemacs
因此,你已经用自己的眼睛看到另外一种方法(正如我们的C程序例子)直到环境变量被导出才能看到它。顺便一提,如果你喜欢,你可以用一行定义和输出一个环境变量,就像下面一样:
代码 1.10: 用一个命令定义和导出环境变量
$ export EDITOR=xemacs
它的工作和两行的版本是一样的。这是一个好的时机去展示如何用unset去除一个环境变量。 代码 1.11: 去除变量
$ unset EDITOR
$ ./myenv
拆分字符串综述
拆分字符串──它是将原始字符串拆分成小一点的,切片──是一个在你平常每天的shell脚本执行中的任务。很多时候,shell脚本需要采用全限定路径,并
(Gentoo)Bash示例,第一部分
找到结束的文件或目录。虽然可以用bash编码实现(而且有趣),但标准basename UNIX可执行程序可以极好地完成此工作: 代码 1.12: 运用basename
$ basename /usr/local/share/doc/foo/foo.txt
foo.txt
$ basename /usr/home/drobbins
drobbins
basename是一个拆分字符串的及其简便的工具。与它相关的被称为dirname返回basename丢弃的"另"一部分路径。 代码 1.13: 运用dirname
$ dirname /usr/local/share/doc/foo/foo.txt
/usr/local/share/doc/foo
$ dirname /usr/home/drobbins/
/usr/home
注意: dirname和basename都不考虑磁盘上的任何文件和文件夹;它们是纯粹的字符串操作命令。
命令替换
需要知道一个很简便的操作,如何创建一个包含可执行命令结果的环境变量。这是很容易做的:
代码 1.14: 创建一个包含命令结果的环境变量
$ MYDIR=`dirname /usr/local/share/doc/foo/foo.txt` $ echo $MYDIR
/usr/local/share/doc/foo
我们上面所做的被称为命令替换。在这个例子中有很多值得注意的。在第一行,我们简单的将命令用反引号括起。这些不是标准的单引号,而是通常在键盘上位于Tab键之上的单引号。我们用bash的交互命令语法来做同样的事情: 代码 1.15: 交互命令替换语法 $ MYDIR=$(dirname /usr/local/share/doc/foo/foo.txt)
$ echo $MYDIR
/usr/local/share/doc/foo
正如我们所见,bash提供了很多执行相同操作的方法。运用命令替换,我们可以将任何命令和命令管道放在` `或$( )之间并把它指定为环境变量。多方便啊!这里是一个如何在命令替换中使用管道的例子:
代码 1.16: 管道命令替换
$ MYFILES=$(ls /etc/| grep pa)
(Gentoo)Bash示例,第一部分
$ echo $MYFILES
pam.d passwd
像个专家一样拆分字符串
尽管basename和dirname是 很棒的工具,但我们可能时常需要更加专业的字符串"拆分"操作而不是仅仅的标准的路径名处理。当我们需要更强的说服力时,我们可以利用bash内建的变量 扩展功能。我们已经使用了标准的变量扩展,就像:${MYVAR}。但是bash还可以自己执行一些便利的字符串拆分。请看一下这些例子: 代码 1.17: 字符串拆分示例
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg
在第一个例子中,我们敲入${MYVAR##*fo}。那么它确切的意思是什么呢?基本上,在${ }中,我们敲入环境变量的名字,两个##和一个通配符("*fo")。然后,bash获取MYVAR, 从字符串"foodforthought.jpg"的起始处查找匹配通配符"*fo"的最长的子串并将其从字符串的开始处拆分。刚开始这有一点难以掌握, 为了感受一下这个特殊的"##"选项是如何工作的,让我们一步步探讨bash是如何完成这个扩展的。首先,它从"foodforthought.jpg的 开始处开始搜索匹配"*fo"通配符的子串。这里是它检查到的子串: 代码 1.18: 子串检查
f
fo MATCHES *fo
foo
food
foodf
foodfo MATCHES *fo
foodfor
foodfort
foodforth
foodfortho
foodforthou
foodforthoug
foodforthought
foodforthought.j
foodforthought.jp
foodforthought.jpg
(Gentoo)Bash示例,第一部分
寻找到匹配的字符串后,你可以看到bash找到两个。它选择了最长匹配,从原始字符串的开始处出去,然后返回结果。
上面的第二种形式的变量扩展和第一种表现的完全相同,只是它只运用一个"#"──并且bash执行了一个几乎相同的过程。正如我们的第一个例子一样,它检 查乐同样的一些子串,除了bash从我们的原始字符串中移除了最短匹配并返回结果。所以,它一检查到"fo"子串,它就从我们的字符串中移除"fo"并返 回"odforthought.jpg"。
这看起来很神秘,所以我们将向你展示一个简单的方法去记住这个功能。当搜索最长匹配时,运用##(因为##比#要长)。当搜索最短匹配时,用#。看,也并 不是那么难去记忆!等等,怎样记住应该使用'#'字符来从字符串起始处移除呢?很简单!注意一下在US键盘上,shift-4是"$",它是bash变量 扩展字符。在键盘上,紧靠在"$"左边是"#"。所以,你可以看到"#"是在"$"的"起始处的",因此(根据我们的记忆法),"#"从字符串的起始处移 除字符。你可能还想知道如何从字符串的末尾移除字符。如果猜到我们用的字符是US键盘上紧靠在"$"右边的"%",正确!这里有几个简单的例子来解释如何 拆分字符串的末尾部分: 代码 1.19: