Linux的壳
在上一篇文章中,我们已经初尝了Shell的好处。由于我们后面将大量借助Shell,所以在这里先简要介绍一下这件工具。
什么是Shell
我们已经说过,Shell是Unix系统提供的文本交互界面。你只需要用键盘来输入命令,就可以和操作系统交互。但这还是不够具体。说到底,Shell其实是一个运行着的程序。这个程序接收到你按下回车键之间的输入,就会对输入的文本进行分析。比如下面这个命令:
$free -h
包括空格在内总共7个字符。Shell程序会通过空格,区分出命令的不同部分。第一个部分是命令名。剩下的部分是选项和参数。在这个例子中,Shell会进一步分析第二个部分,发现这一部分的开头是"-"字符,从而知道它是一个选项。
有了命令名,Shell下一步就要执行该命令名对应的动作。这听起来就像是在戏剧舞台上,演员按照脚本演戏。Shell命令可以分为如下三类:
- Shell内建函数(built-in function)
- 可执行文件(executable file)
- 别名(alias)
Shell的内建函数是保存在Shell内部的脚本。相对应的,可执行文件是保存在Shell之外的脚本。Shell必须在系统中找到对应命令名的可执行文件,才能正确执行。我们可以用绝对路径来告诉Shell可执行文件所在的位置。所谓路径,说明了一个文件在存储空间的位置:
/bin/date
date这个可执行文件位于根目录下的bin文件夹。
如果用户只是给出了命令名,而没有给出准确的位置,那么Shell必须自行搜索一些特殊的位置,也就是所谓的默认路径。Shell会执行第一个名字和命令名相同的可执行文件。这就相当于,Shell帮我们自动补齐了可执行文件的位置信息。我们可以通过which命令,来确定命令名对应的是哪个可执行文件:
$which date
别名是给某个命令一个简称,以后在Shell中就可以通过这个简称来调用对应的命令。在Shell中,我们可以用alias来定义别名:
$alias freak="free -h"
Shell会记住我们的别名定义。以后我在这个Shell中输入命令freak时,都将等价于输入free -h。
在Shell中,我们可以通过type命令来了解命令的类型。如果一个命令是可执行文件,那么type将打印出文件的路径。
$type date
$type pwd
总的来说,Shell就是根据空格和其他特殊符号,来让电脑理解并执行用户要求的动作。到了后面,我们还将看到Shell中其他的特殊符号。
Shell的选择
Shell是文本解释器程序的统称,所以包括了不止一种Shell。常见的Shell有sh、bash、ksh、rsh、csh等。在树莓派中,就安装了sh和bash两个Shell解释器。sh的全名是Bourne Shell。名字中的玻恩就是这个Shell的作者。而bash的全名是Bourne Again Shell。最开始在Unix系统中流行的是sh,而bash作为sh的改进版本,提供了更加丰富的功能。一般来说,都推荐使用bash作为默认的Shell。树莓派,以及其他Linux系统中广泛安装sh,都是出于兼容历史程序的目的。
我们可以通过下面的命令来查看当前的Shell类型:
$echo $SHELL
echo用于在终端打印出文本。而$是一个新的Shell特殊符号。它提示Shell,后面跟随的不是一般的文本,而是用于存储数据的变量。Shell会根据变量名找到真正的文本,替换到变量所在的位置。SHELL变量存储了当前使用的Shell的信息
你可以在bash中用sh命令启动sh,并可以用exit命令从中推出。
命令的选项和参数
我们已经看到,一行命令里还可以包含着选项和参数。总的来说,选项用于控制命令的行为,而参数说明了命令的作用对象。比如说:
$uname -m
在上面的命令中,选项-m影响了命令uname的行为,导致uname输出了树莓派的CPU型号。如果不是该选项的影响,uname输出的将是"Linux"。我们不妨把每个命令看做多功能的瑞士军刀,而选项让命令在不同的功能间切换。由一个"-"引领一个英文字母,这成为短选项。多个短选项的字母可以合在一起,跟在同一个"-"后面。比如,下面的两个命令就等价:
$uname -m -r $uname -mr
此外还有一种长选项,是用"--"引领一整个英文单词,比如:
$date --version
上面的命令将输出date程序的版本信息。
如果说选项控制了瑞士军刀的行为,那么参数就提供了瑞士军刀发挥用场的原材料。就拿echo这个命令来说,它能把字符打印到终端。它选择打印的对象,正是它的参数:
$echo hello
有的时候,选项也会携带变量,以便来说明选项行为的原材料。比如:
$sudo date --set="1999-01-01 08:00:00"
选项"--set"用于设置时间,用等号连接的,就是它的参数。date会把日期设置成这一变量所代表的日期。如果用短选项,那么就要用空格取代等号了:
$sudo date -s "1999-01-01 08:00:00"
值得注意的是,Shell对空格敏感。当一整个参数信息中包含了空格时,我们需要用引号把参数包裹起来,以便Shell能识别出这是一个整体。
需要注意,所谓的选项和参数提供给命令的附加信息。因此,命令最终会拿这些字符串做什么,是由命令自己决定的。因此,有时会发现一些特异的选项或参数用法。这个时候,你就要从文档中寻找答案。
如何了解一个陌生的命令?
每一个Linux系统都带有一套完善的文档,向你解释每个命令的用途。你可以用下面三个命令来调用某个命令的文档信息:
$whatis ls
whatis用很简短的一句话来介绍命令。
$man ls
man会返回命令的帮助手册。对于大部分的Linux自带的命令来说,当作者编写它的时候,都会带有一个帮助文档,告诉用户怎么使用这个命令。man可以说是我们了解Linux最好的百科全书,它不但可以告诉你Linux自带的命令的功能,还可以查询Linux的系统文件和系统调用。如果想要深入学习Linux,就必须要懂得如何用man来查询相关文档。
$info ls
info将返回更详细的帮助信息
Shell的小窍门
1)命令补齐
大多数的Shell都有命令补齐的功能。当你在$的后面输入命令的一部分时,比如"dat"的时候,按Tab键,Linux会帮你打剩下的字符,补充成为"date"。这个过程中,Shell会搜索该命令名的所有可能。如果只有一种可能,那么Shell就会把该文件名补齐。如果不止一种,按第一次Tab会没有反应,按第二次Tab时,终端会打印出所有可能的命令名。比如输入"da",按两次Tab后,终端输出:
dash date
2)文件名补齐
不止是命令名,如果你输入的是作为参数的文件名,Linux也可以帮你补齐。比如说, 当前目录下有a.txt文件。当你输入到ls a.t的时候,按Tab键,Shell会帮你补齐该文件名,成为ls a.txt。
3)历史命令
在Shell中,你还可以用向上箭头来查看之前输入运行的命令。你也可以用
$history
来查询之前输入的命令。
4)中止与暂停命令
当一个命令运行时,你中途想要停止它时,可以用Ctrl + c。如果你只是想暂时停止,使用Ctrl + z。具体机制与信号(signal)有关,我们将在以后介绍
这一章中对Shell的介绍大多是围绕着命令进行。事实上,Shell还能一定程度的编程,从而组合功能单一的命令,完成更复杂的任务。我将在未来进一步探索Shell的这个方面。
总结
命令行: 使用Shell解释输入的字符串,以运行程序
type
echo, ls
sudo
which, whatis, man, info
使用Tab自动补齐,向上箭头查询历史,history
Ctrl + c, Ctrl + z