操作系统为用户提供了两种接口:
第1种是命令接口,用户利用这些命令来组织和控制作业的执行,或者对计算机系统进行管理。
第2种是程序接口,编程人员使用他们来请求操作系统服务。
命令接口为:CLI(命令行界面)和GUI(图形用户界面),TUI(文本用户界面)。
2.1 Shell
Shell为用户提供了输入命令和参数,并且可得到命令执行结果的环境。
Shell作为操作系统的外壳,为用户提供使用操作系统的接口,是命令语言、命令解释程序及程序设计语言的统称。Shell是用户和Linux内核之间的接口程序,当从Shell或其他程序向Linux传递命令时,内核会做出相应的反应。
Linux为用户提供了使用的界面,即Shell,其功能异常强大。Linux中的Shell是一个用C语言编写的程序,是介于用户和Linux内核之间的一个接口程序。
作为命令语言解释器,它拥有自己内建的Shell命令集,它互动式地解释和执行用户输入的命令,即遵循一定的语法,将输入的命令加以解释并传给Linux内核。Shell是使用Linux系统的主要环境,Shell的学习和使用是学习Linux不可或缺的一部分。
作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档,并且以并行的方式协调各个程序的运行。因此,对于用户来说,Shell是最重要的实用程序,深入了解和熟练掌握Shell的特性及其使用方法,是用好Linux系统的关键。
Shell在执行命令时,首先检查该命令是否是内部命令,如果不是,则检查是否是一个应用程序,这里的应用程序可以是Linux本身的实用程序,比如mkdir和ls命令,也可以是购买的商业程序。然后Shell试着在搜索路径(有环境变量$PATH指定,可以执行命令#echo $PATH查看)里查找这些应用程序。搜索路径是一个能找到可执行程序的目录列表。如果用户键入的命令不是一个内部命令,并且在搜索路径里没有找到这个可执行文件,将会显示一条错误信息。如果命令被成功找到,那么Shell的内部命令或应用程序将被分解为一系列的系统调用,进而传递给Linux内核。
Linux有 Bourne Shell(/bin/sh),C Shell(/bin/csh)、Korn Shell(/bin/ksh)、Bourne again Shell(/bin/bash)、Tenex C Shell(tcsh)等Shell。Linux 将 Shell 独立于核心程序之外,使得它就如同一般的应用程序,可以在不影响操作系统本身的情况下进行修改、更新版本或是添加新的功能。
用户登录进入Linux系统时,如果系统默认状态设置为3,即命令行界面,那么用户登录以后得到的就是一个等待输入命令的Shell提示符;如果系统默认状态设置为5,即自动启动图形系统,那么用户可以在GNOME界面依次选择【应用程序】/【附件】/【终端】运行终端仿真程序,在命令提示符后面输入任何命令及参数。
在大部分Linux系统中,三种著名的被广泛支持的Shell 是Bourne Shell(AT&T Shell,在Linux下是BASH)、C Shell(Berkeley Shell,在Linux下是TCSH)和 Korn Shell(Bourne Shell的超集)。这三种Shell在交互(interactive)模式下的表现相当类似,但作为命令文件语言时,在语法和执行效率上就有些不同了。
不论是哪一种Shell,最主要的功能都是解释命令行提示符下输入的命令。Shell分析命令时,将它分解成以空白符分开的符号,空白符包括空格、换行符和制表符<TAB>。
2.1.1 Shell命令行
Linux系统中常用的命令行格式:command [flags] [argument1] [argument2],..
命令行的各单词之间必须由一个或多个空格或制表符隔开,其中flags以“-”开始,多个flags可用一个“-”连起来,如#ls -l -a 与#ls -la相同。
在bash中超级用户的提示符是#,普通用户的提示符是$。
2.1.2 命令和文件名的自动补齐功能在命令行上操作时,一定要勤用【Tab】键。
2.1.3 历史命令与命令别名
1.历史命令
bash?通过历史命令文件保留了一定数目的已经在shell?里输入过的命令,这个数目取决于环境变量HISTSIZE(默认保存1000条命令,可以更改这个值)。
不过bash执行命令时,不会立刻将命令写入历史命令文件,而是先存放在内存的缓冲区中,该缓冲区被称为历史命令列表,等bash退出再将历史命令列表写入历史命令文件,也可以执行#history -w命令要求bash立刻将历史命令列表写入历史命令文件。
当用某帐号登录系统后,历史命令列表将根据一个历史命令文件来初始化。历史命令文件的文件名由环境变量?HISTFILE指定。历史命令文件的缺省名字是.bash_history(点开头的文件是隐藏文件),这个文件通常在用户主目录中(root用户是/root/.bash_history,普通用户是/home/*/.bash_history)。
可以使用?bash?的内部命令?history?,来显示和编辑历史命令。
语法1:history?[n]?
功能:当?history?命令没有参数,将显示整个历史命令列表的内容。如果使用?n?参数,将显示最后?n?个历史命令。
语法2:history?[-a|n|r|w]?[filename]
history?命令各选项及其功能说明见表2-1。
表2-1 history?命令各选项及其功能说明选项
功能
-a
把当前的历史命令记录追加到历史命令文件中
-c
清空历史命令列表
-n
将历史命令文件中的内容加入到当前历史命令列表中
-r
将历史命令文件中的内容更新(替换)当前历史命令列表
-w
把当前历史命令列表的内容写入历史命令文件,并且覆盖历史命令文件的原来内容
filename?
如果?filename?选项没有被指定,history?命令将使用环境变量HISTFILE指定的文件名
实例2-1 自定义历史命令列表第1步:新建一个文件(如/root/history.txt)用来存储自己常用的命令,每条命令占一行。
第2步:执行命令#history -c。
第3步:执行命令#history -r /root/history.txt。
实例2-2 执行历史命令执行历史命令最简单的方法是:使用小键盘上的方向键,按向上箭头向后翻阅历史命令,按向下箭头向前翻阅历史命令,直到找到所需的命令为止,然后按【Enter】键执行该命令。
执行历史命令最便捷的方法是:使用history命令显示历史命令列表,也可以在history命令后跟一个整数表示希望显示最后的多少条命令,每条命令前都有一个序号,可以按照表2-2列出的方法执行历史命令。
表2-2 快速执行历史命令格式
功能
!n
n表示序号(执行history命令可以看到),重新执行第n条命令
!!
重新执行上一条命令
!string
执行最近用到的以string开始的历史命令
!?string[?]
执行最近用到的包含string的历史命令
2.命令别名语法:alias [别名]=[命令名称]
功能:设置命令的别名,如果不加任何参数,仅输入alias命令,将列出目前所有的别名设置。alias命令仅对该次登录系统有效,如果希望每次登录系统都能够使用该命令别名,可以编辑~/.bashrc文件(root用户是/root/.bashrc,普通用户是/home/*/.bashrc),按照如下格式添加一行命令:
alias 别名="要替换的终端命令"
保存.bashrc文件,注销,再次登录系统,就可以使用命令别名了。
 注意:
在定义别名时,等号两边不能有空格。等号右边的命令一般都会包含空格或特殊字符,此时需要用引号。
实例2-3 设置命令别名执行不加任何参数的alias命令,将列出目前所有的别名设置,如下所示。
[root@localhost ~]# alias
alias cp='cp -i'
alias l.='ls -d,* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
#alias showhome='ls -l /home',为“ls -l /home”命令设置别名showhome,然后就可以使用showhome命令了,再执行unalias showhome命令,取消别名设置,此时showhome已经不是命令了。
2.1.4 通配符与文件名变量文件名是命令中最常用的参数。
用户很多时候只知道文件名的一部分,或者用户想同时对具有相同扩展名或以相同字符开始的多个文件进行操作。
Shell提供了一组称为通配符的特殊符号,用于模式匹配,如文件名匹配、路径名搜索、字串查找等。
常用的通配符有(*),(?)和方括号[ ],见表2-3。
表2-3 通配符及其说明通配符
说明
*
匹配任何字符和任何数目的字符组合
匹配任何单个字符
[ ]
匹配任何包含在括号里的单字符
实例2-4 使用通配符(*)
实例之前,先在/root/temp目录下创建ztg1.txt、ztg2.txt、ztg3.txt、ztg4.txt、ztg5.txt、ztg11.txt、ztg22.txt、ztg33.txt文件,其中:
ztg1.txt内容为:“这是文件ztg1.txt中的内容”。
ztg2.txt内容为:“这是文件ztg2.txt中的内容”。
ztg3.txt内容为:“这是文件ztg3.txt中的内容”。
ztg4.txt内容为:“这是文件ztg4.txt中的内容”。
ztg5.txt内容为:“这是文件ztg5.txt中的内容”。
ztg11.txt内容为:“这是文件ztg11.txt中的内容”。
ztg22.txt内容为:“这是文件ztg22.txt中的内容”。
ztg33.txt内容为:“这是文件ztg33.txt中的内容”。
如图2-2所示,第1条命令显示ztg目录中以ztg开头的文件名。执行第2条命令显示ztg目录中所有包含2的文件名。
 注意:
文件名前的圆点(.)和路径名中的斜线(/)必须显式匹配。例如“*”不能匹配.file,而“.*”才可以匹配.file。
实例2-5 使用通配符(?)
如图2-3所示,第1、2条命令使用了通配符(?)进行文件名的模式匹配。
通配符只能匹配单个字符。
 
图2-2 使用通配符(*) 图2-3 使用通配符(?)
实例2-6 使用通配符([ ])
通配符[]能匹配括号中给出的字符或字符范围。同样以前面的目录为例,如图2-4所示,请读者自行分析。

图2-4 使用通配符([ ])
[]代表指定的一个字符范围,只要文件名中[ ]位置处的字符在[ ]中指定的范围之内,那么这个文件名就与这个模式串匹配。方括号中的字符范围可以由直接给出的字符组成,也可以由表示限定范围的起始字符、终止字符及中间的连字符(-)组成。例如,zt[a- d] 与zt[abcd]的作用相同。Shell将把与命令行中指定的模式串相匹配的所有文件名都作为命令的参数,形成最终的命令,然后再执行这个命令。
 注意:
连字符(-)仅在方括号内有效,表示字符范围,如在方括号外面就成为普通字符了。而“*”和“?”只在方括号外面是通配符,若出现在方括号之内,他们也失去通配符的能力,成为普通字符了。
由于“*”,“?”和[ ]对于Shell来说具有比较特殊的意义,因此在正常的文件名中不应出现这些字符。特别是在目录名中不要出现他们,否则Shell匹配起来可能会无穷递归下去。
2.1.5 输入/输出重定向与管道从终端输入资料时,用户输入的资料只能用一次。下次再想用这些资料时就得重新输入。而且在终端上输入时,若输入有误修改起来不是很方便。输出到终端屏幕上的信息只能看不能动。无法对此输出做更多处理,为了解决上述问题,Linux系统为输入、输出的传送引入了另外两种机制,即输入/输出重定向和管道。
Linux下使用标准输入stdin和标准输出stdout来表示每个命令的输入和输出,还使用一个标准错误输出stderr用于输出错误信息。这三个标准输入输出系统缺省与控制终端设备联系在一起。因此,在标准情况下,每个命令通常从它的控制终端中获取输入,将输出打印到控制终端的屏幕上。但是也可以重新定义程序的输入 stdin和输出stdout,将他们重新定向。最基本的用法是将他们重新定向到一个文件,从一个文件获取输入,输出到另一个文件中。
1.输入重定向输入重定向是指把命令或可执行程序的标准输入重定向到指定的文件。
也就是说,输入可以不来自键盘,而来自一个指定的文件。
所以说,输入重定向主要用于改变一个命令的输入源,特别是改变那些需要大量输入的输入源。例如,命令wc统计指定文档包含的行数、单词数和字符数。
如图2-5所示,
第1条命令将一个文件名作为wc命令的参数,将返回该文件所包含的行数、单词数和字符数。
第2条命令是另一种把文件内容传给wc命令的方法,即重定向wc的输入。
输入重定向的一般格式为:命令 < 文件名。
可以用下面的命令把wc命令的输入重定向为httpd.conf文件。

图2-5 输入重定向由于大多数命令都以参数的形式在命令行上指定输入的文件名,所以输入重定向并不经常使用。但是当要使用一个不接受文件名作为输入参数的命令,而需要的输入内容又存在一个文件里时,这时就可以用输入重定向解决问题。
2.输出重定向输出重定向比输入重定向更常用。
输出重定向能把一个命令的输出重定向到一个文件里,而不是显示在屏幕上。
很多情况下都可以使用这种功能。
例如,如果某个命令的输出很多,在屏幕上不能完全显示,可以把它重定向到一个文件中,稍后再用文本编辑器来打开这个文件;
当要保存一个命令的输出时也可以使用这种方法。
还有,输出重定向可以把一个命令的输出当作另一个命令的输入。
还有一种更简单的方法可以把一个命令的输出当作另一个命令的输入,就是使用管道,管道的使用将在后面介绍?。
输出重定向的使用与输入重定向很相似,但是输出重定向的符号是?“>”?。
 注意:
如果“>”符号后边指定的文件已存在,那么这个文件将被重写。
为避免输出重定向中指定的文件被重写,Shell提供了输出重定向的追加手段。追加重定向与输出重定向的功能非常相似,区别仅在于追加重定向的功能是把命令(或可执行程序)的输出结果追加到指定文件的最后,而该文件原有内容不被破坏。如果要将一条命令的输出结果追加到指定文件的后面,可以使用追加重定向操作符“>>”,格式为:命令>>文件名。
实例2-7 使用输出重定向和追加重定向如图2-6所示,第1条命令会在/root/temp目录下创建ztg.txt文件。注意区分两种重定向的异同。

图2-6 输入与追加输出重定向
实例2-8 使用错误输出重定向错误输出也可以重新定向,使用符号“2>”(或追加符号“2>>”)表示对错误输出设备的重定向。
该功能的使用请看图2-7所示。

图2-7 错误输出重定向
3.管道将一个程序或命令的输出作为另一个程序或命令的输入,有两种方法,
一种是通过一个暂存文件将两个命令或程序结合在一起;
另一种是Linux提供的管道功能,这种方法比前一种方法更好,更常用。
管道可以把一系列命令连接起来。这意味着第1个命令的输出会通过管道传给第2个命令,并且作为第2个命令的输入,第2个命令的输出又会作为第3个命令的输入,以此类推。而管道行中最后一个命令的输出才会显示在屏幕上,如果命令行里使用了输出重定向的话,将会放进一个文件里。
可以通过使用管道符“|”来建立一个管道行,下面的示例就是一个管道行:cat?ztg.txt?|?grep?"ztg"?|?wc?-l?。这个管道将?cat?命令的输出作为grep命令的输入。grep命令的输出则是所有包含单词?ztg的行,这个输出又被送给?wc命令。
实例2-9 使用管道符“|”
管道的使用方法如图2-8所示,请读者自行分析。

图2-8 使用管道