Linux Bash脚本编程语言中的美学与哲学

  我承认,我再一次地当了标题党。但是不可否认,这一定是一篇精华随笔。在这一篇中,我将探讨Bash脚本语言中的美学与哲学。 这不是一篇Bash脚本编程的教程,但是却能让人更加深入地了解Bash脚本编程,更加快速地学习Bash脚本编程。 阅读这篇随笔,不需要你有Bash编程的经验,但一定要和我一样热衷于探索各种编程语言的本质,感悟它们的魅力。

  其实早就想写关于Bash的东西了。 我们平时喜欢对编程语言进行分类,比如面向过程的编程语言、面向对象的编程语言、函数式编程语言等等。在我心中,我认为Bash就是一个面向字符串的编程语言。Bash脚本语言的本质:一切皆是字符串。 Bash脚本语言的一切哲学都围绕着字符串:它们从哪里来?到哪里去?使命是什么? Bash脚本语言的一切美学都源自字符串: 由键盘上几乎所有的符号 “$ ~ ! # & ( ) [ ] { } | > < - . , ; * @ ' " ` \ ^” 排列组合而成的极富视觉冲击力的、功能极其复杂的字符串。

Linux Bash Shell入门教程 

一、一切皆是字符串

  Bash是一个Shell,Shell出现的初衷是为了将系统中的各种工具粘合在一起,所以它最根本的功能是调用各种命令。 但是Bash又提供了丰富的编程功能。 我们经常对编程语言进行分类,比如面向过程的语言、面向对象的语言、面向函数的语言等等。 可以把Bash脚本语言看成是一个面向字符串的语言。 Bash语言的本质就是:一切都是字符串。 看看下图中的这些变量:

Linux Bash脚本编程语言中的美学与哲学

  上图是我在交互式的Bash命令行中做的一些演示。在上图中,我对变量分别赋值,不管等号右边是一个没有引号的字符串,还是带有引号的字符串,甚至数字,或者数学表达式,最终的结果,变量里面存储的都是字符串。我使用一个for循环显示所有的变量,可以看到数学表达式也只是以字符串的形式储存,没有被求值。

二、引用和元字符

  如果一切都是没有特殊功能的平凡的字符串,那就无法构成一门编程语言。在Bash中,有很多符号具有特殊含义,比如“$”符号被用于字符串展开,“&”符号用于让命令在后台执行, “|”用作管道, “>” “<”用于输入输出重定向等等。所以在Bash中,虽然同样是字符串,但是被引号包围的字符串和不被引号包围的字符串使用起来是不一样的,被单引号包围的字符串和被双引号包围起来的字符串也是不一样的。

  究竟带引号的字符串和不带引号的字符串使用起来有什么不一样呢?下图是我构建的一些比较典型的例子:

Linux Bash脚本编程语言中的美学与哲学

  在上图中,我展示了Bash中生成字符串的7种方法:大括号展开、波浪符展开、参数展开、命令替换、算术展开、单词分割和文件路径展开。还有两种生成字符串的方式没有讲(Process substitution和历史命令展开)。在使用Bash脚本编程的时候,了解以上7种字符串生成的方式就够了。在交互式使用Bash命令行的时候,还需要了解历史命令展开,熟练使用历史命令展开可以让人事半功倍。

  在上面的图片中可以看到,有一些展开方式在被双引号包围的字符串中是不起作用的,比如大括号展开、波浪符展开、单词分割、文件路径展开,而只有参数展开、命令替换和算术展开是起作用的。从图片中还可以看出,字符串中的参数展开、命令替换和算术展开都是由“$”符号引导,命令替换还可以由“`”引导。所以,可以进一步总结为,在双引号包围的字符串中,只有“$、`、\”这三个字符具有特殊含义。

  如果想让任何一个字符都不具有特殊含义,可以使用单引号将字符串包围。比如使用正则表达式的时候,还比如使用sed、awk等工具的时候,由于sed和awk自己执行的命令中往往包含有很多特殊字符,所以它们的命令最好用单引号包围。 比如使用awk命令显示/etc/passwd文件中的每个用户的用户名和全名,可以使用这个命令 awk -e '{print $1,$5}' ,其中,传递给awk的命令用单引号包围,说明bash不执行其中的任何替换或展开。

  另外一个特殊的字符是“\”,它也是引用的一种。它可以解除紧跟在它后面的一个特殊字符的特殊含义(引用)。之所以需要“\”的存在,是因为在Bash中,有些字符称为元字符,这些字符一旦出现,就会将一个字符串分割为多个子串。如果需要在一个字符串中包含这些元字符本身,就必须对它们进行引用。如下图:

Linux Bash脚本编程语言中的美学与哲学

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8cabaa9b69cf1aca17290f181b262456.html