2011年7月4日星期一

使用 Shell 第三篇

* 命令的排列

现在您将看到一些常用的命令排列。您可能想在一行中给出所有命令,然后就可以把注意力转移到其他地方。没问题,shell 允许您在不同的命令之间,放上特殊的排列字符(queuing characters)这儿将介绍最常用的两种。
请注意,为了看起来更清楚,我在这些字符两旁加了空格。而在实际应用中,您不一定要这么做,‘ls -a ; du -hs’和‘ls -a;du -hs’的效果是一样的。

command1 ; command2

先执行 command1 ,不管 command1 是否出错,接下来执行 command2
例如:
ls -a ; du -hs
将先在屏幕上列出目录中的所有内容,然后列出所有目录及其子目录所占磁盘大小。

command1 && command2

只有当 command1 正确运行完毕后,才执行 command2
例如:
$ ls -a bogusdir && du -hs
将返回 ls: bogusdir: No such file or directory ,而‘du’则根本没有运行(这是因为您没有‘bogusdir’目录)。如果您将符号换成了‘;’,‘du’将被执行。

为了进一步说明‘;’和‘&&’的区别,及一般命令排列的用处,下面举一个经典的例子:Linux 内核的编译和安装。
要编译、安装 Linux ,您需要执行一串命令:‘make dep’、‘make clean’、‘make bzImage’、‘make modules’、‘make modules_install’和‘make install’。如果要等一个命令完成后,再输入下一个,再等,再输入,……,那就太麻烦了。另一方面,每个命令只有当前面的命令都正确执行完毕后,才能开始执行。如果您用‘;’来排列命令,则即使有命令执行失败,后面的也照常运行,最后,您可能在‘/boot’目录下得到一个有问题的内核映像(image)。而用‘&&’:

make dep && make clean && make bzImage && make modules && make modules_install && make install

不需要中途打断,就可以编译内核及其模块,并完成后面的安装。


* 命令的任务调度

当您在终端里运行一个命令或开启一个程序时,终端要等到命令或程序运行完毕后,才能再被使用。在 Unix 中,我们称这样的命令或程序在前台(foreground)运行。如果您想在终端下运行另一个命令,则需要再打开一个新的终端。

但这里还有一个更优雅的办法,称为任务调度(jobbing)或后台(backgrounding)。当您运用任务的调度或将命令置于后台,终端就立即解放了,这样一来,终端立即就可以接受新的输入。为实现这样的目的,您只需在命令后面添加一个 & :

gqview &

告诉 shell 将图片查看器‘GQview’放到后台去执行(即当成 job 来运行)
命令 jobs 将告诉您,在这个终端窗口中,运行着哪些命令与程序:

jobs

             [1]+ Running gqview &           

当您要关闭终端窗口时,这一点就很重要,因为关闭终端将导致所有在其中运行的任务都将被中止,在此例中,如果您关闭了终端,由这个终端开启的 GQview 程序也将被关闭。

但如何将前台运行的一个程序放到后台去?没问题:

gqview

[2]+ Stopped gqview

bg

[2]+ gqview &

组合键 将挂起终端中正在运行的程序,然后您就可以用 bg 命令将其放到后台去执行。

请注意,在后台运行图形应用程序有时候是有用处的,这样可以在终端下显示这个程序的出错信息,虽然这对您可能没有直接的帮助,当如果碰到了麻烦,向别人询问时,这些出错提示就有用武之地了。

一些图形程序,很可能还处在测试期(Beta),尽管在后台执行,也会在终端中输出一些信息。如果您对此不满,可以用下面命令:

command &>/dev/null &

这不仅将程序送到后台执行,还将其输出发到‘/dev/null’文件。‘/dev/null’是系统的“碎纸机” (shredder),所有送到那里的信息都将消失殆尽。


* 命令的替换

命令替换(Command substitution)是一项很实用的功能。我们假设,您想看看 XFree86 文档中的 ‘README.mouse’文件,但您不知道这个文件的位置。但您是位机灵的用户,已经听说了‘locate’命令,也安装了‘slocate’包,您就可以用:

locate README.mouse

发现那个文件在‘/usr/X11R6/lib/X11/doc’。现在您就可以在终端里用‘less’或在文件管理器中进入那个目录然后读取文件。而命令替换可以给您带来一些便捷:

less $(locate README.mouse)

一步到位。命令‘locate README.mouse’的输出(= /usr/X11R6/lib/X11/doc/README.mouse)作为‘less’的参数,然后就可以显示文件内容了。

这种机制的语法是:

command1 $(command2)

除了‘$( )’,您还可以用后引号(backquote)

command1 `command2`

这样虽然可以减少输入,但可读性差,而且很容易就和没有替换功能的一般单引号混淆。我更欣赏前一种方法,但这最终起决于您。

这里有另外一个例子。我们假设,您打算结束一个名为‘rob’的程序。您先得用命令‘pidof’找出相应的进程号(Process ID),然后以这个 PID 为参数,运行‘kill’命令,这样就可以结束‘rob’程序。除了用:

pidof rob
567
kill 567

您还可以试试:

kill `pidof rob`

怎么样,效率有所提高吧?

在下一篇中,我将接着介绍 shell 的另外两种实用的机制:文件名匹配、输出重定向。

没有评论:

发表评论