Shell简介


前言

开篇,我们需要介绍一些Shell 编程基础,主要介绍:

  • Shell
  • Shell 运行环境
  • Shell 基本语法和调试技巧。

可能有基础的同学也不知道怎么做调试,哈哈,本课弥补不足。


什么是 Shell

首先让我们从下图看看 Shell 在整个操作系统中所处的位置吧,该图的外圆(淡蓝色)描述了整个操作系统(比如 Debian/Ubuntu/Slackware 等),内圆描述了操作系统的核心(比如 Linux Kernel),而 ShellGUI 一样作为用户和操作系统之间的接口。

Shell和GUI用户接口


GUI

GUI 提供了一种图形化的用户接口,使用起来非常简便易学;而 Shell 则为用户提供了一种命令行的接口,接收用户的键盘输入,并分析和执行输入字符串中的命令,然后给用户返回执行结果,使用起来可能会复杂一些,但是由于占用的资源少,而且在操作熟练以后可能会提高工作效率,而且具有批处理的功能,因此在某些应用场合还非常流行。


Shell

Shell 作为一种用户接口,它实际上是一个能够解释和分析用户键盘输入,执行输入中的命令,然后返回结果的一个解释程序(Interpreter,例如在 linux 下比较常用的 Bash),我们可以通过下面的命令查看当前的 Shell

$ echo $SHELL
/bin/bash
$ ls -l /bin/bash
-rwxr-xr-x 1 root root 702160 2008-05-13 02:33 /bin/bash

该解释程序不仅能够解释简单的命令,而且可以解释一个具有特定语法结构的文件,这种文件被称作脚本(Script)。

既然该程序可以解释具有一定语法结构的文件,那么我们就可以遵循某一语法来编写它,它有什么样的语法,如何运行,如何调试呢?下面我们以 Bash 为例来讨论这几个方面。


搭建运行环境

为了方便后面的练习,我们先搭建一个基本运行环境:在一个 Linux 操作系统中,有一个运行有 Bash 的命令行在等待我们键入命令,这个命令行可以是图形界面下的 Terminal (例如 Ubuntu 下非常厉害的 Terminator),也可以是字符界面的 Console ,如果你发现当前 Shell 不是 Bash,请用下面的方法替换它:

$ chsh $USER -s /bin/bash
$ su $USER

$USER是当然登录用户的用户名。

或者是简单地键入Bash:

$ bash
$ echo $SHELL  # 确认一下
/bin/bash

这种直接进入bash的方式是临时的。

如果没有安装 Linux 操作系统,我们这里提供了一个Shell环境,机器是站长花钱购买的,不用的男同学请退出哦,以免占用资源,女同事随便。


运行脚本

有了基本的运行环境,那么如何来运行用户键入的命令或者是用户编写好的脚本文件呢?

假设我们编写好了一个** Shell 脚本**,叫 test.sh

第一种方法是确保我们执行的命令具有可执行权限,然后直接键入该命令执行它:

$ chmod +x /path/to/test.sh
$ /path/to/test.sh

第1行的+x,表示给文件执行权限。

第二种方法是直接把脚本作为 Bash 解释器的参数传入:

$ bash /path/to/test.sh

$ source /path/to/test.sh

$ . /path/to/test.sh

这不需要**执行权限**。


基本语法介绍

先来一个 Hello, World 程序。

下面来介绍一个 Shell 程序的基本结构,以 Hello, World 为例:

#!/bin/bash -v
# test.sh
echo "Hello, World"

把上述代码保存为 test.sh,然后通过上面两种不同方式运行,可以看到如下效果。

方法一:

$ chmod +x test.sh
$ ./test.sh
 ./test.sh
 #!/bin/bash -v

 echo "Hello, World"
 Hello, World

方法二:

$ bash test.sh
Hello, World

$ source test.sh
Hello, World

$ . test.sh
Hello, World

我们发现两者运行结果有**区别**,为什么呢?这里我们需要关注一下 test.sh 文件的内容,它仅仅有两行,第二行打印了 Hello, World,两种方法都达到了目的,但是第一种方法却多打印了脚本文件本身的内容,为什么呢?

原因在该文件的第一行,当我们直接运行该脚本文件时,该行告诉操作系统使用用#! 符号之后面的解释器以及相应的参数来解释该脚本文件,通过分析第一行,我们发现对应的解释器以及参数是 /bin/bash -v,而 -v 刚好就是要打印程序的源代码;但是我们在用第二种方法时没有给 Bash 传递任何额外的参数,因此,它仅仅解释了脚本文件本身。


Shell 程序设计过程

Shell 语言作为解释型语言,它的程序设计过程跟编译型语言有些区别,其基本过程如下:

  • 设计算法
  • Shell 编写脚本程序实现算法
  • 直接运行脚本程序

可见它没有编译型语言的"麻烦的"编译和链接过程,不过正是因为这样,它出错时调试起来不是很方便,因为语法错误和逻辑错误都在运行时出现。下面我们简单介绍一下调试方法。


小结

Shell 语言作为一门解释型语言,可以使用大量的现有工具,包括数值计算、符号处理、文件操作、网络操作等,因此,编写过程可能更加高效,但是因为它是解释型的,需要在执行过程中从磁盘上不断调用外部的程序并进行进程之间的切换,在运行效率方面可能有劣势,所以我们应该根据应用场合选择使用 Shell 或是用其他的语言来编程。