Shells与模式

bash shell有交互和非交互两种模式。

交互模式

Ubuntu用户都知道,在Ubuntu中有7个虚拟终端。
桌面环境接管了第7个虚拟终端,于是按下Ctrl-Alt-F7,可以进入一个操作友好的图形用户界面。

即便如此,还是可以通过Ctrl-Alt-F1,来打开shell。打开后,熟悉的图形用户界面消失了,一个虚拟终端展现出来。

看到形如下面的东西,说明shell处于交互模式下:

  1. user@host:~$

接着,便可以输入一系列Unix命令,比如lsgrepcdmkdirrm,来看它们的执行结果。

之所以把这种模式叫做交互式,是因为shell直接与用户交互。

直接使用虚拟终端其实并不是很方便。设想一下,当你想编辑一个文档,与此同时又想执行另一个命令,这种情况下,下面的虚拟终端模拟器可能更适合:

非交互模式

在非交互模式下,shell从文件或者管道中读取命令并执行。当shell解释器执行完文件中的最后一个命令,shell进程终止,并回到父进程。

可以使用下面的命令让shell以非交互模式运行:

  1. sh /path/to/script.sh
  2. bash /path/to/script.sh

上面的例子中,script.sh是一个包含shell解释器可以识别并执行的命令的普通文本文件,shbash是shell解释器程序。你可以使用任何喜欢的编辑器创建script.sh(vim,nano,Sublime Text, Atom等等)。

除此之外,你还可以通过chmod命令给文件添加可执行的权限,来直接执行脚本文件:

  1. chmod +x /path/to/script.sh

这种方式要求脚本文件的第一行必须指明运行该脚本的程序,比如:

  1. #!/bin/bash
  2. echo "Hello, world!"

如果你更喜欢用sh,把#!/bin/bash改成#!/bin/sh即可。#!被称作shebang。之后,就能这样来运行脚本了:

  1. /path/to/script.sh

上面的例子中,我们使用了一个很有用的命令echo来输出字符串到屏幕上。

我们还可以这样来使用shebang:

  1. #!/usr/bin/env bash
  2. echo "Hello, world!"

这样做的好处是,系统会自动在PATH环境变量中查找你指定的程序(本例中的bash)。相比第一种写法,你应该尽量用这种写法,因为程序的路径是不确定的。这样写还有一个好处,操作系统的PATH变量有可能被配置为指向程序的另一个版本。比如,安装完新版本的bash,我们可能将其路径添加到PATH中,来“隐藏”老版本。如果直接用#!/bin/bash,那么系统会选择老版本的bash来执行脚本,如果用#!/usr/bin/env bash,则会使用新版本。

返回值

每个命令都有一个返回值返回状态或者退出状态)。命令执行成功的返回值总是0(零值),执行失败的命令,返回一个非0值(错误码)。错误码必须是一个1到255之间的整数。

在编写脚本时,另一个很有用的命令是exit。这个命令被用来终止当前的执行,并把返回值交给shell。当exit不带任何参数时,它会终止当前脚本的执行并返回在它之前最后一个执行的命令的返回值。

一个程序运行结束后,shell将其返回值赋值给$?环境变量。因此$?变量通常被用来检测一个脚本执行成功与否。

与使用exit来结束一个脚本的执行类似,我们可以使用return命令来结束一个函数的执行并将返回值返回给调用者。当然,也可以在函数内部用exit,这 不但 会中止函数的继续执行,而且 会终止整个程序的执行。