TLCL

参考阅读:http://billie66.github.io/TLCL/book/chap04.html

 

绝对路径

An absolute pathname begins with the root directory and follows the tree branch by branch until the path to the desired directory or file is completed. For example, there is a directory on your system in which most of your system’s programs are installed. The pathname of the directory is /usr/bin. This means from the root directory (represented by the leading slash in the pathname) there is a directory called “usr” which contains a directory called “bin”.

绝对路径开始于根目录,紧跟着目录树的一个个分支,一直到达所期望的目录或文件。 例如,你的系统中有一个目录,大多数系统程序都安装在这个目录下。这个目录的 路径名是 /usr/bin。它意味着从根目录(用开头的“/”表示)开始,有一个叫 “usr” 的 目录包含了目录 “bin”。

[me@linuxbox ~]$ cd /usr/bin
[me@linuxbox bin]$ pwd
/usr/bin
[me@linuxbox bin]$ ls
...Listing of many, many files ...

Now we can see that we have changed the current working directory to /usr/bin and that it is full of files. Notice how the shell prompt has changed? As a convenience, it is usually set up to automatically display the name of the working directory.

我们把工作目录转到 /usr/bin 目录下,里面装满了文件。注意 shell 提示符是怎样改变的吗? 为了方便,通常终端提示符自动显示工作目录名。

相对路径

Where an absolute pathname starts from the root directory and leads to its destination, a relative pathname starts from the working directory. To do this, it uses a couple of special symbols to represent relative positions in the file system tree. These special symbols are “.” (dot) and “..” (dot dot).

绝对路径从根目录开始,直到它的目的地,而相对路径开始于工作目录。 为了做到这个(用相对路径表示), 我们在文件系统树中用一对特殊符号来表示相对位置。 这对特殊符号是 “.” (点) 和 “..” (点点)。

The “.” symbol refers to the working directory and the “..” symbol refers to the working directory’s parent directory. Here is how it works. Let’s change the working directory to /usr/bin again:

符号 “.” 指的是工作目录,”..” 指的是工作目录的父目录。下面的例子说明怎样使用它。 让我们再次把工作目录切换到 /usr/bin:

[me@linuxbox ~]$ cd /usr/bin
[me@linuxbox bin]$ pwd
/usr/bin

Okay, now let’s say that we wanted to change the working directory to the parent of /usr/bin which is /usr. We could do that two different ways. Either with an absolute pathname:

好了,比方说我们想更改工作目录到 /usr/bin 的父目录 /usr。可以通过两种方法来实现。可以使用以下绝对路径名:

[me@linuxbox bin]$ cd /usr
[me@linuxbox usr]$ pwd
/usr

Or, with a relative pathname:

或者, 也可以使用相对路径:

[me@linuxbox bin]$ cd ..
[me@linuxbox usr]$ pwd
/usr

Two different methods with identical results. Which one should we use? The one that requires the least typing!

两种不同的方法,一样的结果。我们应该选哪一个呢? 选输入量最少的那个!

Likewise, we can change the working directory from /usr to /usr/bin in two different ways. Either using an absolute pathname:

同样地,从目录 /usr/ 到 /usr/bin 也有两种途径。可以使用绝对路径:

[me@linuxbox usr]$ cd /usr/bin
[me@linuxbox bin]$ pwd
/usr/bin

Or, with a relative pathname:

或者,也可以用相对路径:

[me@linuxbox usr]$ cd ./bin
[me@linuxbox bin]$ pwd
/usr/bin

Now, there is something important that I must point out here. In almost all cases, you can omit the “./”. It is implied. Typing:

有一件很重要的事,我必须指出来。在几乎所有的情况下,你可以省略”./”。它是隐含的。输入:

[me@linuxbox usr]$ cd bin

does the same thing. In general, if you do not specify a pathname to something, the working directory will be assumed.

实现相同的效果。如果不指定一个文件的路径,那它被默认为在当前工作目录下。

有用的快捷键

In table 3-1 we see some useful ways the current working directory can be quickly changed.

在表3-1中,列举出了一些快速改变当前工作目录的有效方法。

Table 3-1: cd Shortcuts
ShortcutResult
cd Changes the working directory to your home directory.
cd - Changes the working directory to the previous working directory.
cd ~user_name Changes the working directory to the home directory of user_name. For example, cd ~bob will change the directory to the home directory of user “bob.”
表3-1: cd 快捷键
快捷键运行结果
cd 更改工作目录到你的家目录。
cd - 更改工作目录到先前的工作目录。
cd ~user_name 更改工作目录到用户家目录。例如, cd ~bob 会更改工作目录到用户“bob”的家目录。

ls 乐趣

选项和参数

This brings us to a very important point about how most commands work. Commands are often followed by one or more options that modify their behavior, and further, by one or more arguments, the items upon which the command acts. So most commands look kind of like this:

我们将学习一个非常重要的知识点,即大多数命令是如何工作的。命令名经常会带有一个或多个用来更正命令行为的选项, 更进一步,选项后面会带有一个或多个参数,这些参数是命令作用的对象。所以大多数命令看起来像这样:

command -options arguments

Most commands use options consisting of a single character preceded by a dash, for example, “-l”, but many commands, including those from the GNU Project, also support long options, consisting of a word preceded by two dashes. Also, many commands allow multiple short options to be strung together. In this example, the ls command is given two options, the “l” option to produce long format output, and the “t” option to sort the result by the file’s modification time.

大多数命令使用的选项,是由一个中划线加上一个字符组成,例如,“-l”,但是许多命令,包括来自于 GNU 项目的命令,也支持长选项,长选项由两个中划线加上一个字组成。当然, 许多命令也允许把多个短选项串在一起使用。下面这个例子,ls 命令有两个选项, “l” 选项产生长格式输出,“t”选项按文件修改时间的先后来排序。

[me@linuxbox ~]$ ls -lt

We’ll add the long option “–reverse” to reverse the order of the sort:

加上长选项 “–reverse”,则结果会以相反的顺序输出:

[me@linuxbox ~]$ ls -lt --reverse

The ls command has a large number of possible options. The most common are listed in the Table 4-1.

ls 命令有大量的选项。表4-1列出了最常使用的选项。

Table 4-1: Common ls Options
OptionLong OptionDescription
-a --all List all files, even those with names that begin with a period, which are normally not listed(i.e.,hidden).
-d --directory Ordinaryly,if a directory is specified, ls will list the contents of the directory, not the directory itself. Use this option in conjunction with the -l option to see details about the directory rather than its contents.
-F --classify This option will append an indicator character to the end of each listed name. For example, a '/' if the name is a directory.
-h --human-readable In long format listings, display file sizes in human readable format rather than in bytes.
-l   Display results in long format.
-r --reverse Display the results in reverse order. Normally, ls display its results in ascending alphabetical order.
-S   Sort results by file size.
-t   Sort by modification time.
表 4-1: ls 命令选项
选项长选项描述
-a --all 列出所有文件,甚至包括文件名以圆点开头的默认会被隐藏的隐藏文件。
-d --directory 通常,如果指定了目录名,ls 命令会列出这个目录中的内容,而不是目录本身。 把这个选项与 -l 选项结合使用,可以看到所指定目录的详细信息,而不是目录中的内容。
-F --classify 这个选项会在每个所列出的名字后面加上一个指示符。例如,如果名字是 目录名,则会加上一个'/'字符。
-h --human-readable 当以长格式列出时,以人们可读的格式,而不是以字节数来显示文件的大小。
-l   以长格式显示结果。
-r --reverse 以相反的顺序来显示结果。通常,ls 命令的输出结果按照字母升序排列。
-S   命令输出结果按照文件大小来排序。
-t   按照修改时间来排序。

确定文件类型

As we explore the system it will be useful to know what files contain. To do this we will use the file command to determine a file’s type. As we discussed earlier, filenames in Linux are not required to reflect a file’s contents. While a filename like “picture.jpg” would normally be expected to contain a JPEG compressed image, it is not required to in Linux. We can invoke the file command this way:

随着探究操作系统的进行,知道文件包含的内容是很有用的。我们将用 file 命令来确定文件的类型。我们之前讨论过, 在 Linux 系统中,并不要求文件名来反映文件的内容。然而,一个类似 “picture.jpg” 的文件名,我们会期望它包含 JPEG 压缩图像,但 Linux 却不这样要求它。可以这样调用 file 命令:

file filename

When invoked, the file command will print a brief description of the file’s contents. For example:

当调用 file 命令后,file 命令会打印出文件内容的简单描述。例如:

[me@linuxbox ~]$ file picture.jpg
picture.jpg: JPEG image data, JFIF standard 1.01

There are many kinds of files. In fact, one of the common ideas in Unix-like operating systems such as Linux is that “everything is a file.” As we proceed with our lessons, we will see just how true that statement is.

有许多种类型的文件。事实上,在类 Unix 操作系统中比如说 Linux 中,有个普遍的观念就是“一切皆文件”。 随着课程的进行,我们将会明白这句话是多么的正确。

While many of the files on your system are familiar, for example MP3 and JPEG, there are many kinds that are a little less obvious and a few that are quite strange.

虽然系统中许多文件格式是熟悉的,例如 MP3和 JPEG 文件,但也有一些文件格式不太常见,极少数文件相当陌生。

旅行指南

The file system layout on your Linux system is much like that found on other Unix-like systems. The design is actually specified in a published standard called the Linux Filesystem Hierarchy Standard. Not all Linux distributions conform to the standard exactly but most come pretty close.

Linux 系统中,文件系统布局与类 Unix 系统的文件布局很相似。实际上,一个已经发布的标准, 叫做 Linux 文件系统层次标准,详细说明了这种设计模式。不是所有Linux发行版都根据这个标准,但 大多数都是。

Next, we are going to wander around the file system ourselves to see what makes our Linux system tick. This will give you a chance to practice your navigation skills. One of the things we will discover is that many of the interesting files are in plain human- readable text. As we go about our tour, try the following:

下一步,我们将在文件系统中漫游,来了解 Linux 系统的工作原理。这会给你一个温习跳转命令的机会。 我们会发现很多有趣的文件都是纯人类可读文本。下面旅行开始,做做以下练习:

  1. cd into a given directory
  2. List the directory contents with ls -l
  3. If you see an interesting file, determine its contents with file
  4. If it looks like it might be text, try viewing it with less

  1. cd 到给定目录
  2. 列出目录内容 ls -l
  3. 如果看到一个有趣的文件,用 file 命令确定文件内容
  4. 如果文件看起来像文本,试着用 less 命令浏览它

Remember the copy and paste trick! If you are using a mouse, you can double click on a filename to copy it and middle click to paste it into commands.

记得复制和粘贴技巧!如果你正在使用鼠标,双击文件名,来复制它,然后按下鼠标中键,粘贴文件名到命令行中。


As we wander around, don’t be afraid to look at stuff. Regular users are largely prohibited from messing things up. That’s the system administrators job! If a command complains about something, just move on to something else. Spend some time looking around. The system is ours to explore. Remember, in Linux, there are no secrets! Table 4-4 lists just a few of the directories we can explore. Feel free to try more!

在系统中漫游时,不要害怕四处看看。普通用户是很难把东西弄乱的。那是系统管理员的工作! 如果一个命令抱怨一些事情,不要管它,尝试一下别的东西。花一些时间四处看看。 系统是我们自己的,尽情地探究吧。记住在 Linux 中,没有秘密存在! 表4-4仅仅列出了一些我们可以浏览的目录。随意尝试更多!

Table 4-4: Directories Found On Linux Systems
DrectoryComments
/ The root directory.Where everything begins.
/bin Contains binaries (programs) that must be present for the system to boot and run.
/boot Contains the linux kernel, intial RAM disk image (for drivers needed at boot time), and the boot loader.

Interesting files:

  • /boot/grub/grub.conf or menu.lst, which are used to configure the boot loader.
  • /boot/vmlinuz,the linux kernel.
/dev This is a special directory which contains device nodes. "Everything is a file" also applies to devices. Here is where the kernel maintains a list of all the devices it understands.
/etc The /etc directory contains all of the system-wide configuration files. It also contains a collection of shell scripts which start each of the system services at boot time. Everything in this directory should be readable text.

Interesting files:While everything in /etc is interesting, here are some of my all-time favorites:

  • /etc/crontab, a file that defines when automated jobs will run.
  • /etc/fstab, a table of storage devices and their associated mount points.
  • /etc/passwd, a list of the user accounts.
/home In normal configurations, each user is given a directory in /home. Ordinary users can only write files in their home directories. This limitation protects the system from errant user activity.
/lib Contains shared library files used by the core system programs. These are similar to DLLs in Windows.
/lost+found Each formatted partition or device using a Linux file system, such as ext3, will have this directory. It is used in the case of a partial recovery from a file system corruption event. Unless something really bad has happened to your system, this directory will remain empty.
/media On modern Linux systems the /media directory will contain the mount points for removable media such USB drives, CD-ROMs, etc. that are mounted automatically at insertion.
/mnt On older Linux systems, the /mnt directory contains mount points for removable devices that have been mounted manually.
/opt The /opt directory is used to install “optional” software. This is mainly used to hold commercial software products that may be installed on your system.
/proc The /proc directory is special. It's not a real file system in the sense of files stored on your hard drive. Rather, it is a virtual file system maintained by the Linux kernel. The “files” it contains are peepholes into the kernel itself. The files are readable and will give you a picture of how the kernel sees your computer.
/root This is the home directory for the root account.
/sbin This directory contains “system” binaries. These are programs that perform vital system tasks that are generally reserved for the superuser.
/tmp The /tmp directory is intended for storage of temporary, transient files created by various programs. Some configurations cause this directory to be emptied each time the system is rebooted.
/usr The /usr directory tree is likely the largest one on a Linux system. It contains all the programs and support files used by regular users.
/usr/bin /usr/bin contains the executable programs installed by your Linux distribution. It is not uncommon for this directory to hold thousands of programs.
/usr/lib The shared libraries for the programs in /usr/bin.
/usr/local The /usr/local tree is where programs that are not included with your distribution but are intended for system- wide use are installed. Programs compiled from source code are normally installed in /usr/local/bin. On a newly installed Linux system, this tree exists, but it will be empty until the system administrator puts something in it.
/usr/sbin Contains more system administration programs.
/usr/share /usr/share contains all the shared data used by programs in /usr/bin. This includes things like default configuration files, icons, screen backgrounds, sound files, etc.
/usr/share/doc Most packages installed on the system will include some kind of documentation. In /usr/share/doc, we will find documentation files organized by package.
/var With the exception of /tmp and /home, the directories we have looked at so far remain relatively static, that is, their contents don't change. The /var directory tree is where data that is likely to change is stored. Various databases, spool files, user mail, etc. are located here.
/var/log /var/log contains log files, records of various system activity. These are very important and should be monitored from time to time. The most useful one is /var/log/messages. Note that for security reasons on some systems, you must be the superuser to view log files.
表 4-4: Linux 系统中的目录
目录评论
/ 根目录,万物起源。
/bin 包含系统启动和运行所必须的二进制程序。
/boot

包含 Linux 内核、初始 RAM 磁盘映像(用于启动时所需的驱动)和 启动加载程序。

有趣的文件:

  • /boot/grub/grub.conf or menu.lst, 被用来配置启动加载程序。
  • /boot/vmlinuz,Linux 内核。
/dev 这是一个包含设备结点的特殊目录。“一切都是文件”,也适用于设备。 在这个目录里,内核维护着所有设备的列表。
/etc

这个目录包含所有系统层面的配置文件。它也包含一系列的 shell 脚本, 在系统启动时,这些脚本会开启每个系统服务。这个目录中的任何文件应该是可读的文本文件。

有趣的文件:虽然/etc 目录中的任何文件都有趣,但这里只列出了一些我一直喜欢的文件:

  • /etc/crontab, 定义自动运行的任务。
  • /etc/fstab,包含存储设备的列表,以及与他们相关的挂载点。
  • /etc/passwd,包含用户帐号列表。
/home 在通常的配置环境下,系统会在/home 下,给每个用户分配一个目录。普通用户只能 在自己的目录下写文件。这个限制保护系统免受错误的用户活动破坏。
/lib 包含核心系统程序所使用的共享库文件。这些文件与 Windows 中的动态链接库相似。
/lost+found 每个使用 Linux 文件系统的格式化分区或设备,例如 ext3文件系统, 都会有这个目录。当部分恢复一个损坏的文件系统时,会用到这个目录。这个目录应该是空的,除非文件系统 真正的损坏了。
/media 在现在的 Linux 系统中,/media 目录会包含可移动介质的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些介质连接到计算机之后,会自动地挂载到这个目录结点下。
/mnt 在早些的 Linux 系统中,/mnt 目录包含可移动介质的挂载点。
/opt 这个/opt 目录被用来安装“可选的”软件。这个主要用来存储可能 安装在系统中的商业软件产品。
/proc 这个/proc 目录很特殊。从存储在硬盘上的文件的意义上说,它不是真正的文件系统。 相反,它是一个由 Linux 内核维护的虚拟文件系统。它所包含的文件是内核的窥视孔。这些文件是可读的, 它们会告诉你内核是怎样监管计算机的。
/root root 帐户的家目录。
/sbin 这个目录包含“系统”二进制文件。它们是完成重大系统任务的程序,通常为超级用户保留。
/tmp 这个/tmp 目录,是用来存储由各种程序创建的临时文件的地方。一些配置导致系统每次 重新启动时,都会清空这个目录。
/usr 在 Linux 系统中,/usr 目录可能是最大的一个。它包含普通用户所需要的所有程序和文件。
/usr/bin /usr/bin 目录包含系统安装的可执行程序。通常,这个目录会包含许多程序。
/usr/lib 包含由/usr/bin 目录中的程序所用的共享库。
/usr/local 这个/usr/local 目录,是非系统发行版自带程序的安装目录。 通常,由源码编译的程序会安装在/usr/local/bin 目录下。新安装的 Linux 系统中会存在这个目录, 并且在管理员安装程序之前,这个目录是空的。
/usr/sbin 包含许多系统管理程序。
/usr/share /usr/share 目录包含许多由/usr/bin 目录中的程序使用的共享数据。 其中包括像默认的配置文件、图标、桌面背景、音频文件等等。
/usr/share/doc 大多数安装在系统中的软件包会包含一些文档。在/usr/share/doc 目录下, 我们可以找到按照软件包分类的文档。
/var 除了/tmp 和/home 目录之外,相对来说,目前我们看到的目录是静态的,这是说, 它们的内容不会改变。/var 目录存放的是动态文件。各种数据库,假脱机文件, 用户邮件等等,都位于在这里。
/var/log 这个/var/log 目录包含日志文件、各种系统活动的记录。这些文件非常重要,并且 应该时时监测它们。其中最重要的一个文件是/var/log/messages。注意,为了系统安全,在一些系统中, 你必须是超级用户才能查看这些日志文件。

符号链接

As we look around, we are likely to see a directory listing with an entry like this:

在我们到处查看时,我们可能会看到一个目录,列出像这样的一条信息:

lrwxrwxrwx 1 root root 11 2007-08-11 07:34 libc.so.6 -> libc-2.6.so

Notice how the first letter of the listing is “l” and the entry seems to have two filenames? This is a special kind of a file called a symbolic link (also known as a soft link or symlink.) In most Unix-like systems it is possible to have a file referenced by multiple names. While the value of this may not be obvious, it is really a useful feature.

注意看,为何这条信息第一个字符是“l”,并且有两个文件名呢? 这是一个特殊文件,叫做符号链接(也称为软链接或者 symlink )。 在大多数“类 Unix” 系统中, 有可能一个文件被多个文件名所指向。虽然这种特性的意义并不明显,但它真的很有用。

Picture this scenario: a program requires the use of a shared resource of some kind contained in a file named “foo,” but “foo” has frequent version changes. It would be good to include the version number in the filename so the administrator or other interested party could see what version of “foo” is installed. This presents a problem. If we change the name of the shared resource, we have to track down every program that might use it and change it to look for a new resource name every time a new version of the resource is installed. That doesn’t sound like fun at all.

描绘一下这样的情景:一个程序要求使用某个包含在名为“foo”文件中的共享资源,但是“foo”经常改变版本号。 这样,在文件名中包含版本号,会是一个好主意,因此管理员或者其它相关方,会知道安装了哪个“foo”版本。 这会导致另一个问题。如果我们更改了共享资源的名字,那么我们必须跟踪每个可能使用了 这个共享资源的程序,当每次这个资源的新版本被安装后,都要让使用了它的程序去寻找新的资源名。 这听起来很没趣。

Here is where symbolic links save the day. Let’s say we install version 2.6 of “foo,” which has the filename “foo-2.6” and then create a symbolic link simply called “foo” that points to “foo-2.6.” This means that when a program opens the file “foo”, it is actually opening the file “foo-2.6”. Now everybody is happy. The programs that rely on “foo” can find it and we can still see what actual version is installed. When it is time to upgrade to “foo-2.7,” we just add the file to our system, delete the symbolic link “foo” and create a new one that points to the new version. Not only does this solve the problem of the version upgrade, but it also allows us to keep both versions on our machine. Imagine that “foo-2.7” has a bug (damn those developers!) and we need to revert to the old version. Again, we just delete the symbolic link pointing to the new version and create a new symbolic link pointing to the old version.

这就是符号链接存在至今的原因。比方说,我们安装了文件 “foo” 的 2.6 版本,它的 文件名是 “foo-2.6”,然后创建了叫做 “foo” 的符号链接,这个符号链接指向 “foo-2.6”。 这意味着,当一个程序打开文件 “foo” 时,它实际上是打开文件 “foo-2.6”。 现在,每个人都很高兴。依赖于 “foo” 文件的程序能找到这个文件,并且我们能知道安装了哪个文件版本。 当升级到 “foo-2.7” 版本的时候,仅添加这个文件到文件系统中,删除符号链接 “foo”, 创建一个指向新版本的符号链接。这不仅解决了版本升级问题,而且还允许在系统中保存两个不同的文件版本。 假想 “foo-2.7” 有个错误(该死的开发者!),那我们得回到原来的版本。 一样的操作,我们只需要删除指向新版本的符号链接,然后创建指向旧版本的符号链接就可以了。

The directory listing above (from the /lib directory of a Fedora system) shows a symbolic link called “libc.so.6” that points to a shared library file called “libc-2.6.so.” This means that programs looking for “libc.so.6” will actually get the file “libc-2.6.so.” We will learn how to create symbolic links in the next chapter.

在上面列出的目录(来自于 Fedora 的 /lib 目录)展示了一个叫做 “libc.so.6” 的符号链接,这个符号链接指向一个 叫做 “libc-2.6.so” 的共享库文件。这意味着,寻找文件 “libc.so.6” 的程序,实际上得到是文件 “libc-2.6.so”。 在下一章节,我们将学习如何建立符号链接。

硬链接

While we are on the subject of links, we need to mention that there is a second type of link called a hard link. Hard links also allow files to have multiple names, but they do it in a different way. We’ll talk more about the differences between symbolic and hard links in the next chapter.

讨论到链接问题,我们需要提一下,还有一种链接类型,叫做硬链接。硬链接同样允许文件有多个名字, 但是硬链接以不同的方法来创建多个文件名。在下一章中,我们会谈到更多符号链接与硬链接之间的差异问题。

通配符

Before we begin using our commands, we need to talk about a shell feature that makes these commands so powerful. Since the shell uses filenames so much, it provides special characters to help you rapidly specify groups of filenames. These special characters are called wildcards. Using wildcards (which is also known as globbing) allow you to select filenames based on patterns of characters. The table below lists the wildcards and what they select:

在开始使用命令之前,我们需要介绍一个使命令行如此强大的 shell 特性。因为 shell 频繁地使用 文件名,shell 提供了特殊字符来帮助你快速指定一组文件名。这些特殊字符叫做通配符。 使用通配符(也以文件名代换著称)允许你依据字符的组合模式来选择文件名。下表列出这些通配符 以及它们所选择的对象:

Table 5-1: Wildcards
WildcardMeaning
* Matches any characters
? Matches any single character
[characters] Matches any character that is a member of the set characters
[!characters] Matches any character that is not a member of the set characters
[[:class:]] Matches any character that is a member of the specified class
表5-1: 通配符
通配符意义
* 匹配任意多个字符(包括零个或一个)
? 匹配任意一个字符(不包括零个)
[characters] 匹配任意一个属于字符集中的字符
[!characters] 匹配任意一个不是字符集中的字符
[[:class:]] 匹配任意一个属于指定字符类中的字符

Table 5-2 lists the most commonly used character classes:

表5-2列出了最常使用的字符类:

Table 5-2: Commonly Used Character Classes
Character ClassMeaning
[:alnum:] Matches any alphanumeric character
[:alpha:] Matches any alphabetic character
[:digit:] Matches any numeral
[:lower:] Matches any lowercase letter
[:upper:] Matches any uppercase letter
表5-2: 普遍使用的字符类
字符类意义
[:alnum:] 匹配任意一个字母或数字
[:alpha:] 匹配任意一个字母
[:digit:] 匹配任意一个数字
[:lower:] 匹配任意一个小写字母
[:upper:] 匹配任意一个大写字母

Using wildcards makes it possible to construct very sophisticated selection criteria for filenames. Here are some examples of patterns and what they match:

借助通配符,为文件名构建非常复杂的选择标准成为可能。下面是一些类型匹配的范例:

Table 5-3: Wildcard Examples
PatternMatches
* All files
g* All file beginning with "g"
b*.txt Any file beginning with "b" followed by any characters and ending with ".txt"
Data??? Any file beginning with "Data" followed by exactly three characters
[abc]* Any file beginning with either an "a", a "b", or a "c"
BACKUP.[0-9][0-9][0-9] Any file beginning with "BACKUP." followed by exactly three numerals
[[:upper:]]* Any file beginning with an uppercase letter
[![:digit:]]* Any file not beginning with a numeral
*[[:lower:]123] Any file ending with a lowercase letter or the numerals "1", "2", or "3"
表5-3: 通配符范例
模式匹配对象
* 所有文件
g* 文件名以“g”开头的文件
b*.txt 以"b"开头,中间有零个或任意多个字符,并以".txt"结尾的文件
Data??? 以“Data”开头,其后紧接着3个字符的文件
[abc]* 文件名以"a","b",或"c"开头的文件
BACKUP.[0-9][0-9][0-9] 以"BACKUP."开头,并紧接着3个数字的文件
[[:upper:]]* 以大写字母开头的文件
[![:digit:]]* 不以数字开头的文件
*[[:lower:]123] 文件名以小写字母结尾,或以 “1”,“2”,或 “3” 结尾的文件

ln — 创建链接

The ln command is used to create either hard or symbolic links. It is used in one of two ways:

ln 命令既可创建硬链接,也可以创建符号链接。可以用其中一种方法来使用它:

ln file link

to create a hard link, and:

创建硬链接,和:

ln -s item link

to create a symbolic link where “item” is either a file or a directory.

创建符号链接,”item” 可以是一个文件或是一个目录。

硬链接

Hard links are the original Unix way of creating links; symbolic links are more modern. By default, every file has a single hard link that gives the file its name. When we create a hard link, we create an additional directory entry for a file. Hard links have two important limitations:

与更加现代的符号链接相比,硬链接是最初 Unix 创建链接的方式。每个文件默认会有一个硬链接, 这个硬链接给予文件名字。我们每创建一个硬链接,就为一个文件创建了一个额外的目录项。 硬链接有两个重要局限性:

  1. A hard link cannot reference a file outside its own file system. This means a link may not reference a file that is not on the same disk partition as the link itself.

  2. A hard link may not reference a directory.

  1. 一个硬链接不能关联它所在文件系统之外的文件。这是说一个链接不能关联 与链接本身不在同一个磁盘分区上的文件。

  2. 一个硬链接不能关联一个目录。

A hard link is indistinguishable from the file itself. Unlike a symbolic link, when you list a directory containing a hard link you will see no special indication of the link. When a hard link is deleted, the link is removed but the contents of the file itself continue to exist (that is, its space is not deallocated) until all links to the file are deleted. It is important to be aware of hard links because you might encounter them from time to time, but modern practice prefers symbolic links, which we will cover next.

一个硬链接和文件本身没有什么区别。不像符号链接,当你列出一个包含硬链接的目录 内容时,你会看到没有特殊的链接指示说明。当一个硬链接被删除时,这个链接 被删除,但是文件本身的内容仍然存在(这是说,它所占的磁盘空间不会被重新分配), 直到所有关联这个文件的链接都删除掉。知道硬链接很重要,因为你可能有时 会遇到它们,但现在实际中更喜欢使用符号链接,下一步我们会讨论符号链接。

符号链接

Symbolic links were created to overcome the limitations of hard links. Symbolic links work by creating a special type of file that contains a text pointer to the referenced file or directory. In this regard, they operate in much the same way as a Windows shortcut though of course, they predate the Windows feature by many years ;-)

创建符号链接是为了克服硬链接的局限性。符号链接生效,是通过创建一个 特殊类型的文件,这个文件包含一个关联文件或目录的文本指针。在这一方面, 它们和 Windows 的快捷方式差不多,当然,符号链接早于 Windows 的快捷方式 很多年;-)

A file pointed to by a symbolic link, and the symbolic link itself are largely indistinguishable from one another. For example, if you write some something to the symbolic link, the referenced file is also written to. However when you delete a symbolic link, only the link is deleted, not the file itself. If the file is deleted before the symbolic link, the link will continue to exist, but will point to nothing. In this case, the link is said to be broken. In many implementations, the ls command will display broken links in a distinguishing color, such as red, to reveal their presence.

一个符号链接指向一个文件,而且这个符号链接本身与其它的符号链接几乎没有区别。 例如,如果你往一个符号链接里面写入东西,那么相关联的文件也被写入。然而, 当你删除一个符号链接时,只有这个链接被删除,而不是文件自身。如果先于符号链接 删除文件,这个链接仍然存在,但是不指向任何东西。在这种情况下,这个链接被称为 坏链接。在许多实现中,ls 命令会以不同的颜色展示坏链接,比如说红色,来显示它们 的存在。

The concept of links can seem very confusing, but hang in there. We’re going to try all this stuff and it will, hopefully, become clear.

关于链接的概念,看起来很迷惑,但不要胆怯。我们将要试着练习 这些命令,希望,它变得清晰起来。

练习:

创建硬链接

Now we’ll try some links. First the hard links. We’ll create some links to our data file like so:

现在,我们试着创建链接。首先是硬链接。我们创建一些关联我们 数据文件的链接:

[me@linuxbox playground]$ ln fun fun-hard
[me@linuxbox playground]$ ln fun dir1/fun-hard
[me@linuxbox playground]$ ln fun dir2/fun-hard

So now we have four instances of the file “fun”. Let’s take a look our playground directory:

所以现在,我们有四个文件”fun”的实例。看一下目录 playground 中的内容:

[me@linuxbox playground]$ ls -l
total 16
drwxrwxr-x 2 me  me 4096 2008-01-14 16:17 dir1
drwxrwxr-x 2 me  me 4096 2008-01-14 16:17 dir2
-rw-r--r-- 4 me  me 1650 2008-01-10 16:33 fun
-rw-r--r-- 4 me  me 1650 2008-01-10 16:33 fun-hard

One thing you notice is that the second field in the listing for fun and fun-hard both contain a “4” which is the number of hard links that now exist for the file. You’ll remember that a file will always have at least one because the file’s name is created by a link. So, how do we know that fun and fun-hard are, in fact, the same file? In this case, ls is not very helpful. While we can see that fun and fun-hard are both the same size (field 5), our listing provides no way to be sure. To solve this problem, we’re going to have to dig a little deeper.

注意到一件事,列表中,文件 fun 和 fun-hard 的第二个字段是”4”,这个数字 是文件”fun”的硬链接数目。你要记得一个文件至少有一个硬链接,因为文件 名就是由链接创建的。那么,我们怎样知道实际上 fun 和 fun-hard 是同一个文件呢? 在这个例子里,ls 不是很有用。虽然我们能够看到 fun 和 fun-hard 文件大小一样 (第五字段),但我们的列表没有提供可靠的信息来确定(这两个文件一样)。 为了解决这个问题,我们更深入的研究一下。

When thinking about hard links, it is helpful to imagine that files are made up of two parts: the data part containing the file’s contents and the name part which holds the file’s name. When we create hard links, we are actually creating additional name parts that all refer to the same data part. The system assigns a chain of disk blocks to what is called an inode, which is then associated with the name part. Each hard link therefore refers to a specific inode containing the file’s contents.

当考虑到硬链接的时候,我们可以假设文件由两部分组成:包含文件内容的数据部分和持有文件名的名字部分 ,这将有助于我们理解这个概念。当我们创建文件硬链接的时候,实际上是为文件创建了额外的名字部分, 并且这些名字都关联到相同的数据部分。这时系统会分配一连串的磁盘块给所谓的索引节点,然后索引节点与文 件名字部分相关联。因此每一个硬链接都关系到一个具体的包含文件内容的索引节点。

The ls command has a way to reveal this information. It is invoked with the “-i” option:

ls 命令有一种方法,来展示(文件索引节点)的信息。在命令中加上”-i”选项:

[me@linuxbox playground]$ ls -li
total 16
12353539 drwxrwxr-x 2 me  me 4096  2008-01-14  16:17  dir1
12353540 drwxrwxr-x 2 me  me 4096  2008-01-14  16:17  dir2
12353538 -rw-r--r-- 4 me  me 1650  2008-01-10  16:33  fun
12353538 -rw-r--r-- 4 me  me 1650  2008-01-10  16:33  fun-hard

In this version of the listing, the first field is the inode number and, as we can see, both fun and fun-hard share the same inode number, which confirms they are the same file.

在这个版本的列表中,第一字段表示文件索引节点号,正如我们所见到的, fun 和 fun-hard 共享一样的索引节点号,这就证实这两个文件是同一个文件。

创建符号链接

Symbolic links were created to overcome the two disadvantages of hard links: hard links cannot span physical devices and hard links cannot reference directories, only files. Symbolic links are a special type of file that contains a text pointer to the target file or directory.

建立符号链接的目的是为了克服硬链接的两个缺点:硬链接不能跨越物理设备, 硬链接不能关联目录,只能是文件。符号链接是文件的特殊类型,它包含一个指向 目标文件或目录的文本指针。

Creating symbolic links is similar to creating hard links:

符号链接的建立过程相似于创建硬链接:

[me@linuxbox playground]$ ln -s fun fun-sym
[me@linuxbox playground]$ ln -s ../fun dir1/fun-sym
[me@linuxbox playground]$ ln -s ../fun dir2/fun-sym

The first example is pretty straightforward, we simply add the “-s” option to create a symbolic link rather than a hard link. But what about the next two? Remember, when we create a symbolic link, we are creating a text description of where the target file is relative to the symbolic link. It’s easier to see if we look at the ls output:

第一个例子相当直接,在 ln 命令中,简单地加上”-s”选项就可以创建一个符号链接, 而不是一个硬链接。下面两个例子又是怎样呢? 记住,当我们创建一个符号链接 的时候,会建立一个目标文件在哪里和符号链接有关联的文本描述。如果我们看看 ls 命令的输出结果,比较容易理解。

[me@linuxbox playground]$ ls -l dir1
total 4
-rw-r--r-- 4 me  me 1650 2008-01-10 16:33 fun-hard
lrwxrwxrwx 1 me  me    6 2008-01-15 15:17 fun-sym -> ../fun

The listing for fun-sym in dir1 shows that is it a symbolic link by the leading “l” in the first field and that it points to “../fun”, which is correct. Relative to the location of fun-sym, fun is in the directory above it. Notice too, that the length of the symbolic link file is 6, the number of characters in the string “../fun” rather than the length of the file to which it is pointing.

目录 dir1 中,fun-sym 的列表说明了它是一个符号链接,通过在第一字段中的首字符”l” 可知,并且它还指向”../fun”,也是正确的。相对于 fun-sym 的存储位置,fun 在它的 上一个目录。同时注意,符号链接文件的长度是6,这是字符串”../fun”所包含的字符数, 而不是符号链接所指向的文件长度。

When creating symbolic links, you can either use absolute pathnames:

当建立符号链接时,你既可以使用绝对路径名:

ln -s /home/me/playground/fun dir1/fun-sym

or relative pathnames, as we did in our earlier example. Using relative pathnames is more desirable because it allows a directory containing symbolic links to be renamed and/or moved without breaking the links.

也可用相对路径名,正如前面例题所展示的。使用相对路径名更令人满意, 因为它允许一个包含符号链接的目录重命名或移动,而不会破坏链接。

In addition to regular files, symbolic links can also reference directories:

除了普通文件,符号链接也能关联目录:

[me@linuxbox playground]$ ln -s dir1 dir1-sym
[me@linuxbox playground]$ ls -l
total 16
...省略


到底什么是命令?

A command can be one of four different things:

命令可以是下面四种形式之一:

  1. An executable program like all those files we saw in /usr/bin. Within this category, programs can be compiled binaries such as programs written in C and C++, or programs written in scripting languages such as the shell, perl, python, ruby, etc.

  2. A command built into the shell itself. bash supports a number of commands internally called shell builtins. The cd command, for example, is a shell builtin.

  3. A shell function. These are miniature shell scripts incorporated into the environment. We will cover configuring the environment and writing shell functions in later chapters, but for now, just be aware that they exist.

  4. An alias. Commands that we can define ourselves, built from other commands.

  1. 是一个可执行程序,就像我们所看到的位于目录/usr/bin 中的文件一样。 这一类程序可以是用诸如 C 和 C++语言写成的程序编译的二进制文件, 也可以是由诸如shell,perl,python,ruby等等脚本语言写成的程序 。

  2. 是一个内建于 shell 自身的命令。bash 支持若干命令,内部叫做 shell 内部命令 (builtins)。例如,cd 命令,就是一个 shell 内部命令。

  3. 是一个 shell 函数。这些是小规模的 shell 脚本,它们混合到环境变量中。 在后续的章节里,我们将讨论配置环境变量以及书写 shell 函数。但是现在, 仅仅意识到它们的存在就可以了。

  4. 是一个命令别名。我们可以定义自己的命令,建立在其它命令之上。

识别命令

It is often useful to know exactly which of the four kinds of commands is being used and Linux provides a couple of ways to find out.

这经常很有用,能确切地知道正在使用四类命令中的哪一类。Linux 提供了一对方法来 弄明白命令类型。

type - 显示命令的类型

The type command is a shell builtin that displays the kind of command the shell will execute, given a particular command name. It works like this:

type 命令是 shell 内部命令,它会显示命令的类别,给出一个特定的命令名(做为参数)。 它像这样工作:

type command

Where “command” is the name of the command you want to examine. Here are some examples:

“command”是你要检测的命令名。这里有些例子:

[me@linuxbox ~]$ type type
type is a shell builtins
[me@linuxbox ~]$ type ls
ls is aliased to `ls --color=tty`
[me@linuxbox ~]$ type cp
cp is /bin/cp

Here we see the results for three different commands. Notice that the one for ls (taken from a Fedora system) and how the ls command is actually an alias for the ls command with the “--color=tty” option added. Now we know why the output from ls is displayed in color!

我们看到这三个不同命令的检测结果。注意,ls 命令(在 Fedora 系统中)的检查结果,ls 命令实际上 是 ls 命令加上选项”--color=tty”的别名。现在我们知道为什么 ls 的输出结果是有颜色的!

which - 显示一个可执行程序的位置

Sometimes there is more than one version of an executable program installed on a system. While this is not very common on desktop systems, it’s not unusual on large servers. To determine the exact location of a given executable, the which command is used:

有时候在一个操作系统中,不只安装了可执行程序的一个版本。虽然在桌面系统中这并不普遍, 但在大型服务器中却很平常。为了确定所给定的执行程序的准确位置,使用 which 命令:

[me@linuxbox ~]$ which ls
/bin/ls

which only works for executable programs, not builtins nor aliases that are substitutes for actual executable programs. When we try to use which on a shell builtin, for example, cd, we either get no response or an error message:

这个命令只对可执行程序有效,不包括内建命令和命令别名,别名是真正的可执行程序的替代物。 当我们试着使用 shell 内建命令时,例如,cd 命令,我们或者得不到回应,或者是个错误信息:

[me@linuxbox ~]$ which cd
/usr/bin/which: no cd in
(/opt/jre1.6.0_03/bin:/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/opt/jre1
.6.0_03/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/home/me/bin)

which is a fancy way of saying “command not found.”

说“命令没有找到”,真是很奇特。

用别名(alias)创建你自己的命令

Now for our very first experience with programming! We will create a command of our own using the alias command. But before we start, we need to reveal a small command line trick. It’s possible to put more than one command on a line by separating each command with a semicolon character. It works like this:

现在是时候,感受第一次编程经历了!我们将用 alias 命令创建我们自己的命令。但在 开始之前,我们需要展示一个命令行小技巧。可以把多个命令放在同一行上,命令之间 用”;”分开。它像这样工作:

command1; command2; command3...

Here’s the example we will use:

我们会用到下面的例子:

[me@linuxbox ~]$ cd /usr; ls; cd -
bin  games    kerberos  lib64    local  share  tmp
...
[me@linuxbox ~]$

As we can see, we have combined three commands on one line. First we change directory to /usr then list the directory and finally return to the original directory (by using ‘cd -‘) so we end up where we started. Now let’s turn this sequence into a new command using alias. The first thing we have to do is dream up a name for our new command. Let’s try “test”. Before we do that, it would be a good idea to find out if the name “test” is already being used. To find out, we can use the type command again:

正如我们看到的,我们在一行上联合了三个命令。首先更改目录到/usr,然后列出目录 内容,最后回到原始目录(用命令”cd -“),结束在开始的地方。现在,通过 alias 命令 把这一串命令转变为一个命令。我们要做的第一件事就是为我们的新命令构想一个名字。 比方说”test”。在使用”test”之前,查明是否”test”命令名已经存在系统中,是个很不错 的主意。为了查清此事,可以使用 type 命令:

[me@linuxbox ~]$ type test
test is a shell builtin

Oops! The name “test” is already taken. Let’s try “foo”:

哦!”test”名字已经被使用了。试一下”foo”:

[me@linuxbox ~]$ type foo
bash: type: foo: not found

Great! “foo” is not taken. So let’s create our alias:

太棒了!”foo”还没被占用。创建命令别名:

[me@linuxbox ~]$ alias foo='cd /usr; ls; cd -'

Notice the structure of this command:

注意命令结构:

alias name='string'

After the command “alias” we give alias a name followed immediately (no whitespace allowed) by an equals sign, followed immediately by a quoted string containing the meaning to be assigned to the name. After we define our alias, it can be used anywhere the shell would expect a command. Let’s try it:

在命令”alias”之后,输入“name”,紧接着(没有空格)是一个等号,等号之后是 一串用引号引起的字符串,字符串的内容要赋值给 name。我们定义了别名之后, 这个命令别名可以使用在任何地方。试一下:

[me@linuxbox ~]$ foo
bin   games   kerberos  lib64    local   share  tmp
...
[me@linuxbox ~]$

We can also use the type command again to see our alias:

我们也可以使用 type 命令来查看我们的别名:

[me@linuxbox ~]$ type foo
foo is aliased to `cd /usr; ls ; cd -'

To remove an alias, the unalias command is used, like so:

删除别名,使用 unalias 命令,像这样:

[me@linuxbox ~]$ unalias foo
[me@linuxbox ~]$ type foo
bash: type: foo: not found

While we purposefully avoided naming our alias with an existing command name, it is not uncommon to do so. This is often done to apply a commonly desired option to each invocation of a common command. For instance, we saw earlier how the ls command is often aliased to add color support:

虽然我们有意避免使用已经存在的命令名来命名我们的别名,但这是常做的事情。通常, 会把一个普遍用到的选项加到一个经常使用的命令后面。例如,之前见到的 ls 命令,会 带有色彩支持:

[me@linuxbox ~]$ type ls
ls is aliased to 'ls --color=tty'

To see all the aliases defined in the environment, use the alias command without arguments. Here are some of the aliases defined by default on a Fedora system. Try and figure out what they all do:

要查看所有定义在系统环境中的别名,使用不带参数的 alias 命令。下面在 Fedora 系统中 默认定义的别名。试着弄明白,它们是做什么的:

[me@linuxbox ~]$ alias
alias l.='ls -d .* --color=tty'
...

There is one tiny problem with defining aliases on the command line. They vanish when your shell session ends. In a later chapter, we will see how to add our own aliases to the files that establish the environment each time we log on, but for now, enjoy the fact that we have taken our first, albeit tiny, step into the world of shell programming!

在命令行中定义别名有点儿小问题。当你的 shell 会话结束时,它们会消失。随后的章节里, 我们会了解怎样把自己的别名添加到文件中去,每次我们登录系统,这些文件会建立系统环境。 现在,好好享受我们刚经历过的,步入 shell 编程世界的第一步吧,虽然微小。

标准输入、输出和错误

Many of the programs that we have used so far produce output of some kind. This output often consists of two types. First, we have the program’s results; that is, the data the program is designed to produce, and second, we have status and error messages that tell us how the program is getting along. If we look at a command like ls, we can see that it displays its results and its error messages on the screen.

到目前为止,我们用到的许多程序都会产生某种输出。这种输出,经常由两种类型组成。 第一,程序运行结果;这是说,程序要完成的功能。第二,我们得到状态和错误信息, 这些告诉我们程序进展。如果我们观察一个命令,像 ls,会看到它的运行结果和错误信息 显示在屏幕上。

Keeping with the Unix theme of “everything is a file,” programs such as ls actually send their results to a special file called standard output (often expressed as stdout) and their status messages to another file called standard error (stderr). By default, both standard output and standard error are linked to the screen and not saved into a disk file. In addition, many programs take input from a facility called standard input (stdin) which is, by default, attached to the keyboard.

与 Unix 主题“任何东西都是一个文件”保持一致,程序,比方说 ls,实际上把他们的运行结果 输送到一个叫做标准输出的特殊文件(经常用 stdout 表示),而它们的状态信息则送到另一个 叫做标准错误的文件(stderr)。默认情况下,标准输出和标准错误都连接到屏幕,而不是 保存到磁盘文件。除此之外,许多程序从一个叫做标准输入(stdin)的设备得到输入,默认情况下, 标准输入连接到键盘。

I/O redirection allows us to change where output goes and where input comes from. Normally, output goes to the screen and input comes from the keyboard, but with I/O redirection, we can change that.

I/O 重定向允许我们更改输出地点和输入来源。一般地,输出送到屏幕,输入来自键盘, 但是通过 I/O 重定向,我们可以做出改变。

标准输出重定向

I/O redirection allows us to redefine where standard output goes. To redirect standard output to another file besides the screen, we use the “>” redirection operator followed by the name of the file. Why would we want to do this? It’s often useful to store the output of a command in a file. For example, we could tell the shell to send the output of the ls command to the file ls-output.txt instead of the screen:

I/O 重定向允许我们来重定义标准输出的地点。我们使用 “>” 重定向符后接文件名将标准输出重定向到除屏幕 以外的另一个文件。为什么我们要这样做呢?因为有时候把一个命令的运行结果存储到 一个文件很有用处。例如,我们可以告诉 shell 把 ls 命令的运行结果输送到文件 ls-output.txt 中去, 由文件代替屏幕。

[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt

Here, we created a long listing of the /usr/bin directory and sent the results to the file ls-output.txt. Let’s examine the redirected output of the command:

这里,我们创建了一个长长的目录/usr/bin 列表,并且输送程序运行结果到文件 ls-output.txt 中。 我们检查一下重定向的命令输出结果:

[me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1   me   me    167878 2008-02-01 15:07 ls-output.txt

Good; a nice, large, text file. If we look at the file with less, we will see that the file ls-output.txt does indeed contain the results from our ls command:

好;一个不错的大型文本文件。如果我们用 less 阅读器来查看这个文件,我们会看到文件 ls-output.txt 的确包含 ls 命令的执行结果。

[me@linuxbox ~]$ less ls-output.txt

Now, let’s repeat our redirection test, but this time with a twist. We’ll change the name of the directory to one that does not exist:

现在,重复我们的重定向测试,但这次有改动。我们把目录换成一个不存在的目录。

[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt
ls: cannot access /bin/usr: No such file or directory

We received an error message. This makes sense since we specified the non-existent directory /bin/usr, but why was the error message displayed on the screen rather than being redirected to the file ls-output.txt? The answer is that the ls program does not send its error messages to standard output. Instead, like most well-written Unix programs, it sends its error messages to standard error. Since we only redirected standard output and not standard error, the error message was still sent to the screen. We’ll see how to redirect standard error in just a minute, but first, let’s look at what happened to our output file:

我们收到一个错误信息。这讲得通,因为我们指定了一个不存在的目录/bin/usr, 但是为什么这条错误信息显示在屏幕上而不是被重定向到文件 ls-output.txt?答案是, ls 程序不把它的错误信息输送到标准输出。反而,像许多写得不错的 Unix 程序,ls 把 错误信息送到标准错误。因为我们只是重定向了标准输出,而没有重定向标准错误, 所以错误信息被送到屏幕。马上,我们将知道怎样重定向标准错误,但是首先看一下 我们的输出文件发生了什么事情。

me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1 me   me    0 2008-02-01 15:08 ls-output.txt

The file now has zero length! This is because, when we redirect output with the “>” redirection operator, the destination file is always rewritten from the beginning. Since our ls command generated no results and only an error message, the redirection operation started to rewrite the file and then stopped because of the error, resulting in its truncation. In fact, if we ever need to actually truncate a file (or create a new, empty file) we can use a trick like this:

文件长度为零!这是因为,当我们使用 “>” 重定向符来重定向输出结果时,目标文件总是从开头被重写。 因为我们 ls 命令没有产生运行结果,只有错误信息,重定向操作开始重写文件,然后 由于错误而停止,导致文件内容清空。事实上,如果我们需要清空一个文件内容(或者创建一个 新的空文件),可以使用这样的技巧:

[me@linuxbox ~]$ > ls-output.txt

Simply using the redirection operator with no command preceding it will truncate an existing file or create a new, empty file.

简单地使用重定向符,没有命令在它之前,这会清空一个已存在文件的内容或是 创建一个新的空文件。

So, how can we append redirected output to a file instead of overwriting the file from the beginning? For that, we use the “>>” redirection operator, like so:

所以,怎样才能把重定向结果追加到文件内容后面,而不是从开头重写文件?为了这个目的, 我们使用”>>“重定向符,像这样:

[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt

Using the “>>” operator will result in the output being appended to the file. If the file does not already exist, it is created just as though the “>” operator had been used. Let’s put it to the test:

使用”>>“操作符,将导致输出结果添加到文件内容之后。如果文件不存在,文件会 被创建,就如使用了”>”操作符。把它放到测试中:

[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt
[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt
[me@linuxbox ~]$ ls -l /usr/bin >> ls-output.txt
[me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1 me   me    503634 2008-02-01 15:45 ls-output.txt

We repeated the command three times resulting in an output file three times as large.

我们重复执行命令三次,导致输出文件大小是原来的三倍。

标准错误重定向

Redirecting standard error lacks the ease of a dedicated redirection operator. To redirect standard error we must refer to its file descriptor. A program can produce output on any of several numbered file streams. While we have referred to the first three of these file streams as standard input, output and error, the shell references them internally as file descriptors zero, one and two, respectively. The shell provides a notation for redirecting files using the file descriptor number. Since standard error is the same as file descriptor number two, we can redirect standard error with this notation:

标准错误重定向没有专用的重定向操作符。为了重定向标准错误,我们必须参考其文件描述符。 一个程序可以在几个编号的文件流中的任一个上产生输出。虽然我们已经将这些文件流的前 三个称作标准输入、输出和错误,shell 内部分别将其称为文件描述符0、1和2。shell 使用文件描述符提供 了一种表示法来重定向文件。因为标准错误和文件描述符2一样,我们用这种 表示法来重定向标准错误:

[me@linuxbox ~]$ ls -l /bin/usr 2> ls-error.txt

The file descriptor “2” is placed immediately before the redirection operator to perform the redirection of standard error to the file ls-error.txt.

文件描述符”2”,紧挨着放在重定向操作符之前,来执行重定向标准错误到文件 ls-error.txt 任务。

重定向标准输出和错误到同一个文件

There are cases in which we may wish to capture all of the output of a command to a single file. To do this, we must redirect both standard output and standard error at the same time. There are two ways to do this. First, the traditional way, which works with old versions of the shell:

可能有这种情况,我们希望捕捉一个命令的所有输出到一个文件。为了完成这个,我们 必须同时重定向标准输出和标准错误。有两种方法来完成任务。第一个,传统的方法, 在旧版本 shell 中也有效:

[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt 2>&1

Using this method, we perform two redirections. First we redirect standard output to the file ls-output.txt and then we redirect file descriptor two (standard error) to file descriptor one (standard output) using the notation 2>&1.

使用这种方法,我们完成两个重定向。首先重定向标准输出到文件 ls-output.txt,然后 重定向文件描述符2(标准错误)到文件描述符1(标准输出)使用表示法2>&1。


Notice that the order of the redirections is significant. The redirection of standard error must always occur after redirecting standard output or it doesn’t work. In the example above,

注意重定向的顺序安排非常重要。标准错误的重定向必须总是出现在标准输出 重定向之后,要不然它不起作用。上面的例子,

>ls-output.txt 2>&1

redirects standard error to the file ls-output.txt, but if the order is changed to

重定向标准错误到文件 ls-output.txt,但是如果命令顺序改为:

2>&1 >ls-output.txt

standard error is directed to the screen.

则标准错误定向到屏幕。


Recent versions of bash provide a second, more streamlined method for performing this combined redirection:

现在的 bash 版本提供了第二种方法,更精简合理的方法来执行这种联合的重定向。

[me@linuxbox ~]$ ls -l /bin/usr &> ls-output.txt

In this example, we use the single notation &> to redirect both standard output and standard error to the file ls-output.txt.

在这个例子里面,我们使用单单一个表示法 &> 来重定向标准输出和错误到文件 ls-output.txt。

处理不需要的输出

Sometimes “silence is golden,” and we don’t want output from a command, we just want to throw it away. This applies particularly to error and status messages. The system provides a way to do this by redirecting output to a special file called “/dev/null”. This file is a system device called a bit bucket which accepts input and does nothing with it. To suppress error messages from a command, we do this:

有时候“沉默是金”,我们不想要一个命令的输出结果,只想把它们扔掉。这种情况 尤其适用于错误和状态信息。系统通过重定向输出结果到一个叫做”/dev/null”的特殊文件, 为我们提供了解决问题的方法。这个文件是系统设备,叫做位存储桶,它可以 接受输入,并且对输入不做任何处理。为了隐瞒命令错误信息,我们这样做:

[me@linuxbox ~]$ ls -l /bin/usr 2> /dev/null



波浪线展开

As you may recall from our introduction to the cd command, the tilde character (“~”) has a special meaning. When used at the beginning of a word, it expands into the name of the home directory of the named user, or if no user is named, the home directory of the current user:

可能你从我们对 cd 命令的介绍中回想起来,波浪线字符(“~”)有特殊的含义。当它用在 一个单词的开头时,它会展开成指定用户的家目录名,如果没有指定用户名,则展开成当前用户的家目录:

[me@linuxbox ~]$ echo ~
/home/me


算术表达式展开

The shell allows arithmetic to be performed by expansion. This allow us to use the shell prompt as a calculator:

shell 在展开中执行算数表达式。这允许我们把 shell 提示当作计算器来使用:

[me@linuxbox ~]$ echo $((2 + 2))
4

Arithmetic expansion uses the form:

算术表达式展开使用这种格式:

$((expression))

where expression is an arithmetic expression consisting of values and arithmetic operators.

(以上括号中的)表达式是指算术表达式,它由数值和算术操作符组成。

Arithmetic expansion only supports integers (whole numbers, no decimals), but can perform quite a number of different operations. Here are a few of the supported operators:

算术表达式只支持整数(全部是数字,不带小数点),但是能执行很多不同的操作。这里是 一些它支持的操作符:

Table 8-1: Arithmetic Operators
OperatorDescription
+ Addition
- Subtraction
* Multiplication
/ Division(but remember, since expansion only supports integer arithmetic, results are integers.)
% Modulo, which simply means, "remainder".
** Exponentiation
表 8-1: 算术操作符
操作符说明
+
-
*
/ 除(但是记住,因为展开只是支持整数除法,所以结果是整数。)
% 取余,只是简单的意味着,“余数”
** 取幂

Spaces are not significant in arithmetic expressions and expressions may be nested. For example, to multiply five squared by three:

在算术表达式中空格并不重要,并且表达式可以嵌套。例如,5的平方乘以3:

[me@linuxbox ~]$ echo $(($((5**2)) * 3))
75

Single parentheses may be used to group multiple subexpressions. With this technique, we can rewrite the example above and get the same result using a single expansion instead of two:

一对括号可以用来把多个子表达式括起来。通过这个技术,我们可以重写上面的例子, 同时用一个展开代替两个,来得到一样的结果:

[me@linuxbox ~]$ echo $(((5**2) * 3))
75

Here is an example using the division and remainder operators. Notice the effect of integer division:

这是一个使用除法和取余操作符的例子。注意整数除法的结果:

[me@linuxbox ~]$ echo Five divided by two equals $((5/2))
Five divided by two equals 2
[me@linuxbox ~]$ echo with $((5%2)) left over.
with 1 left over.


花括号展开

Perhaps the strangest expansion is called brace expansion. With it, you can create multiple text strings from a pattern containing braces. Here’s an example:

可能最奇怪的展开是花括号展开。通过它,你可以从一个包含花括号的模式中 创建多个文本字符串。这是一个例子:

[me@linuxbox ~]$ echo Front-{A,B,C}-Back
Front-A-Back Front-B-Back Front-C-Back

Patterns to be brace expanded may contain a leading portion called a preamble and a trailing portion called a postscript. The brace expression itself may contain either a comma-separated list of strings, or a range of integers or single characters. The pattern may not contain embedded whitespace. Here is an example using a range of integers:

花括号展开模式可能包含一个开头部分叫做报头,一个结尾部分叫做附言。花括号表达式本身可 能包含一个由逗号分开的字符串列表,或者一个整数区间,或者单个的字符的区间。这种模式不能 嵌入空白字符。这个例子中使用了一个整数区间:

[me@linuxbox ~]$ echo Number_{1..5}
Number_1  Number_2  Number_3  Number_4  Number_5

A range of letters in reverse order:

倒序排列的字母区间:

[me@linuxbox ~]$ echo {Z..A}
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

Brace expansions may be nested:

花括号展开可以嵌套:

[me@linuxbox ~]$ echo a{A{1,2},B{3,4}}b
aA1b aA2b aB3b aB4b

So what is this good for? The most common application is to make lists of files or directories to be created. For example, if we were photographers and had a large collection of images that we wanted to organize into years and months, the first thing we might do is create a series of directories named in numeric “Year-Month” format. This way, the directory names will sort in chronological order. We could type out a complete list of directories, but that’s a lot of work and it’s error-prone too. Instead, we could do this:

那么这对什么有好处呢?最常见的应用是,创建一系列的文件或目录列表。例如, 如果我们是摄影师,有大量的相片。我们想把这些相片按年月先后组织起来。首先, 我们要创建一系列以数值”年-月”形式命名的目录。通过这种方式,可以使目录名按照 年代顺序排列。我们可以手动键入整个目录列表,但是工作量太大了,并且易于出错。 反之,我们可以这样做:

[me@linuxbox ~]$ mkdir Pics
[me@linuxbox ~]$ cd Pics
[me@linuxbox Pics]$ mkdir {2007..2009}-0{1..9} {2007..2009}-{10..12}
[me@linuxbox Pics]$ ls
2007-01 2007-07 2008-01 2008-07 2009-01 2009-07
2007-02 2007-08 2008-02 2008-08 2009-02 2009-08
2007-03 2007-09 2008-03 2008-09 2009-03 2009-09
2007-04 2007-10 2008-04 2008-10 2009-04 2009-10
2007-05 2007-11 2008-05 2008-11 2009-05 2009-11
2007-06 2007-12 2008-06 2008-12 2009-06 2009-12

Pretty slick!

棒极了!

键盘高级操作技巧

移动光标

The following table lists the keys used to move the cursor:

下表列出了移动光标所使用的按键:

Table 9-1: Cursor Movement Commands
KeyAction
Ctrl-a Move cursor to the beginning of the line.
Ctrl-e Move cursor to the end of the line.
Ctrl-f Move cursor forward one character;same as the right arrow key.
Ctrl-b Move cursor backward one character;same as the left arrow key.
Alt-f Move cursor forward one word.
Alt-b Move cursor backward one word.
Ctrl-l Clear the screen and move the cursor to the top left corner. The clear command does the same thing.
表9-1: 光标移动命令
按键行动
Ctrl-a 移动光标到行首。
Ctrl-e 移动光标到行尾。
Ctrl-f 光标前移一个字符;和右箭头作用一样。
Ctrl-b 光标后移一个字符;和左箭头作用一样。
Alt-f 光标前移一个字。
Alt-b 光标后移一个字。
Ctrl-l 清空屏幕,移动光标到左上角。clear 命令完成同样的工作。

修改文本

Table 9-2 lists keyboard commands that are used to edit characters on the command line.

表9-2列出了键盘命令,这些命令用来在命令行中编辑字符。

Table 9-2: Text Editing Commands
KeyAction
Ctrl-d Delete the character at the cursor location
Ctrl-t Transpose(exchange)the character at the cursor location with the one preceding it.
Alt-t Transpose the word at the cursor location with the one preceding it.
Alt-l Convert the characters from the cursor location to the end of the word to lowercase.
Alt-u Convert the characters from the cursor location to the end of the word to uppercase.
表9-2: 文本编辑命令
按键行动
Ctrl-d 删除光标位置的字符。
Ctrl-t 光标位置的字符和光标前面的字符互换位置。
Alt-t 光标位置的字和其前面的字互换位置。
Alt-l 把从光标位置到字尾的字符转换成小写字母。
Alt-u 把从光标位置到字尾的字符转换成大写字母。

剪切和粘贴文本

The Readline documentation uses the terms killing and yanking to refer to what we would commonly call cutting and pasting. Items that are cut are stored in a buffer called the kill-ring.

Readline 的文档使用术语 killing 和 yanking 来指我们平常所说的剪切和粘贴。 剪切下来的本文被存储在一个叫做剪切环(kill-ring)的缓冲区中。

Table 9-3: Cut And Paste Commands
KeyAction
Ctrl-k Kill text from the cursor location to the end of line.
Ctrl-u Kill text from the cursor location to the beginning of the line.
Alt-d Kill text from the cursor location to the end of the current word.
Alt-Backspace Kill text from the cursor location to the beginning of the word. If the cursor is at the beginning of a word, kill the previous word.
Ctrl-y Yank text from the kill-ring and insert it at the cursor location.
表9-3: 剪切和粘贴命令
按键行动
Ctrl-k 剪切从光标位置到行尾的文本。
Ctrl-u 剪切从光标位置到行首的文本。
Alt-d 剪切从光标位置到词尾的文本。
Alt-Backspace 剪切从光标位置到词头的文本。如果光标在一个单词的开头,剪切前一个单词。
Ctrl-y 把剪切环中的文本粘贴到光标位置。

查看进程

The most commonly used command to view processes (there are several) is ps. The ps program has a lot of options, but in it simplest form it is used like this:

查看进程,最常使用地命令(有几个命令)是 ps(process status)。ps 程序有许多选项,它最简单地使用形式是这样的:

[me@linuxbox ~]$ ps
PID TTY           TIME CMD
5198 pts/1    00:00:00 bash
10129 pts/1   00:00:00 ps

The result in this example lists two processes, process 5198 and process 10129, which are bash and ps respectively. As we can see, by default, ps doesn’t show us very much, just the processes associated with the current terminal session. To see more, we need to add some options, but before we do that, let’s look at the other fields produced by ps. TTY is short for “Teletype,” and refers to the controlling terminal for the process. Unix is showing its age here. The TIME field is the amount of CPU time consumed by the process. As we can see, neither process makes the computer work very hard.

上例中,列出了两个进程,进程 5198 和进程 10129,各自代表命令 bash 和 ps。正如我们所看到的, 默认情况下,ps 不会显示很多进程信息,只是列出与当前终端会话相关的进程。为了得到更多信息, 我们需要加上一些选项,但是在这样做之前,我们先看一下 ps 命令运行结果的其它字段。 TTY 是 “Teletype”(直译电传打字机) 的简写,是指进程的控制终端。TTY足足显示了 Unix 的年代久远。TIME 字段表示 进程所消耗的 CPU 时间数量。正如我们所看到的,这两个进程使计算机工作起来很轻松。

If we add an option, we can get a bigger picture of what the system is doing:

如果给 ps 命令加上选项,我们可以得到更多关于系统运行状态的信息:

[me@linuxbox ~]$ ps x
PID TTY   STAT   TIME COMMAND
2799 ?    Ssl    0:00 /usr/libexec/bonobo-activation-server –ac
2820 ?    Sl     0:01 /usr/libexec/evolution-data-server-1.10 --

and many more...

Adding the “x” option (note that there is no leading dash) tells ps to show all of our processes regardless of what terminal (if any) they are controlled by. The presence of a “?” in the TTY column indicates no controlling terminal. Using this option, we see a list of every process that we own.

加上 “x” 选项(注意没有开头的 “-“ 字符),告诉 ps 命令,展示所有进程,不管它们由什么 终端(如果有的话)控制。在 TTY 一栏中出现的 “?” ,表示没有控制终端。使用这个 “x” 选项,可以 看到我们所拥有的每个进程的信息。

Since the system is running a lot of processes, ps produces a long list. It is often helpful to pipe the output from ps into less for easier viewing. Some option combinations also produce long lines of output, so maximizing the terminal emulator window may be a good idea, too.

因为系统中正运行着许多进程,所以 ps 命令的输出结果很长。为了方便查看,将ps的输出管道 到less中通常很有帮助。一些选项组合也会产生很长的输出结果,所以最大化 终端仿真器窗口可能也是一个好主意。

A new column titled STAT has been added to the output. STAT is short for “state” and reveals the current status of the process:

输出结果中,新添加了一栏,标题为 STAT 。STAT 是 “state” 的简写,它揭示了进程当前状态:

Table 11-1: Process States
StateMeaning
R Running. This means that the process is running or ready to run.
S Sleeping. A process is not running; rather, it is waiting for an event, such as a keystroke or network packet.
D Uninterruptible Sleep. Process is waiting for I/O such as a disk drive.
T Stopped. Process has been instructed to stop. More on this later.
Z A defunct or “zombie” process. This is a child process that has terminated, but has not been cleaned up by its parent.
< A high priority process. It's possible to grant more importance to a process, giving it more time on the CPU. This property of a process is called niceness. A process with high priority is said to be less nice because it's taking more of the CPU's time, which leaves less for everybody else.
N A low priority process. A process with low priority (a “nice” process) will only get processor time after other processes with higher priority have been serviced.
表11-1: 进程状态
状态含义
R 运行中。这意味着,进程正在运行或准备运行。
S 正在睡眠。进程没有运行,而是,正在等待一个事件, 比如说,一个按键或者网络分组。
D 不可中断睡眠。进程正在等待 I/O,比方说,一个磁盘驱动器的 I/O。
T 已停止. 已经指示进程停止运行。稍后介绍更多。
Z 一个死进程或“僵尸”进程。这是一个已经终止的子进程,但是它的父进程还没有清空它。 (父进程没有把子进程从进程表中删除)
< 一个高优先级进程。这可能会授予一个进程更多重要的资源,给它更多的 CPU 时间。 进程的这种属性叫做 niceness。具有高优先级的进程据说是不好的(less nice), 因为它占用了比较多的 CPU 时间,这样就给其它进程留下很少时间。
N 低优先级进程。 一个低优先级进程(一个“nice”进程)只有当其它高优先级进程被服务了之后,才会得到处理器时间。

The process state may be followed by other characters. These indicate various exotic process characteristics. See the ps man page for more detail.

进程状态信息之后,可能还跟随其他的字符。这表示各种外来进程的特性。详细信息请看 ps 手册页。

Another popular set of options is “aux” (without a leading dash). This gives us even more information:

另一个流行的选项组合是 “aux”(不带开头的”-“字符)。这会给我们更多信息:

[me@linuxbox ~]$ ps aux
USER   PID  %CPU  %MEM     VSZ    RSS  TTY   STAT   START   TIME  COMMAND
root     1   0.0   0.0    2136    644  ?     Ss     Mar05   0:31  init
root     2   0.0   0.0       0      0  ?     S&lt;     Mar05   0:00  [kt]

and many more...

This set of options displays the processes belonging to every user. Using the options without the leading dash invokes the command with “BSD style” behavior. The Linux version of ps can emulate the behavior of the ps program found in several different Unix implementations. With these options, we get these additional columns:

这个选项组合,能够显示属于每个用户的进程信息。使用这个选项,可以唤醒 “BSD 风格” 的输出结果。 Linux 版本的 ps 命令,可以模拟几个不同 Unix 版本中的 ps 程序的行为。通过这些选项,我们得到 这些额外的列。

Table 11-2: BSD Style ps Column Headers
HeaderMeaning
USER User ID. This is the owner of the process.
%CPU CPU usage in percent
%MEM Memory usage in percent
VSZ Virtual memory size
RSS Resident Set Size. The amount of physical memory (RAM) the process is using in kilobytes.
START Time when the process started. For values over twenty four hours, a date is used.
表11-2: BSD 风格的 ps 命令列标题
标题含义
USER 用户 ID. 进程的所有者。
%CPU 以百分比表示的 CPU 使用率
%MEM 以百分比表示的内存使用率
VSZ 虚拟内存大小
RSS 进程占用的物理内存的大小,以千字节为单位。
START 进程启动的时间。若它的值超过24小时,则用天表示。

用 top 命令动态查看进程

While the ps command can reveal a lot about what the machine is doing, it provides only a snapshot of the machine’s state at the moment the ps command is executed. To see a more dynamic view of the machine’s activity, we use the top command:

虽然 ps 命令能够展示许多计算机运行状态的信息,但是它只是提供 ps 命令执行时刻的机器状态快照。 为了看到更多动态的信息,我们使用 top 命令:

[me@linuxbox ~]$ top

The top program displays a continuously updating (by default, every 3 seconds) display of the system processes listed in order of process activity. The name “top” comes from the fact that the top program is used to see the “top” processes on the system. The top display consists of two parts: a system summary at the top of the display, followed by a table of processes sorted by CPU activity:

top 程序以进程活动顺序显示连续更新的系统进程列表。(默认情况下,每三秒钟更新一次),”top”这个名字 来源于 top 程序是用来查看系统中“顶端”进程的。top 显示结果由两部分组成: 最上面是系统概要,下面是进程列表,以 CPU 的使用率排序。

top - 14:59:20 up 6:30, 2 users, load average: 0.07, 0.02, 0.00
Tasks: 109 total,   1 running,  106 sleeping,    0 stopped,    2 zombie
Cpu(s): 0.7%us, 1.0%sy, 0.0%ni, 98.3%id, 0.0%wa, 0.0%hi, 0.0%si
Mem:   319496k total,   314860k used,   4636k free,   19392k buff
Swap:  875500k total,   149128k used,   726372k free,  114676k cach

 PID  USER       PR   NI   VIRT   RES   SHR  S %CPU  %MEM   TIME+    COMMAND
6244  me         39   19  31752  3124  2188  S  6.3   1.0   16:24.42 trackerd
....

The system summary contains a lot of good stuff. Here’s a rundown:

其中系统概要包含许多有用信息。下表是对系统概要的说明:

Table 11-3: top Information Fields
RowFieldMeaning
1 top Name of the program
  14:59:20 Current time of day.
  up 6:30 This is called uptime. It is the amount of time since the machine was last booted. In this example, the system has been up for six and a half hours.
  2 users There are two users logged in.
  load average: Load average refers to the number of processes that are waiting to run, that is, the number of processes that are in a runnable state and are sharing the CPU. Three values are shown, each for a different period of time. The first is the average for the last 60 seconds, the next the previous 5 minutes, and finally the previous 15 minutes. Values under 1.0 indicate that the machine is not busy.
2 Tasks: This summarizes the number of processes and their various process states.
3 Cpu(s): This row describes the character of the activities that the CPU is performing.
  0.7%us 0.7% of the CPU is being used for user processes. This means processes outside of the kernel itself.
  1.0%sy 1.0% of the CPU is being used for system (kernel) processes.
  0.0%ni 0.0% of the CPU is being used by “nice” (low priority) processes.
  98.3%id 98.3% of the CPU is idle.
  0.0%wa 0.0% of the CPU is waiting for I/O.
4 Mem: Shows how physical RAM is being used.
5 Swap: Shows how swap space (virtual memory) is being used.
表11-3: top 命令信息字段
行号字段意义
1 top 程序名。
  14:59:20 当前时间。
  up 6:30 这是正常运行时间。它是计算机从上次启动到现在所运行的时间。 在这个例子里,系统已经运行了六个半小时。
  2 users 有两个用户登录系统。
  load average: 加载平均值是指,等待运行的进程数目,也就是说,处于可以运行状态并共享 CPU 的进程个数。 这里展示了三个数值,每个数值对应不同的时间段。第一个是最后60秒的平均值, 下一个是前5分钟的平均值,最后一个是前15分钟的平均值。若平均值低于1.0,则指示计算机 工作不忙碌。
2 Tasks: 总结了进程数目和这些进程的各种状态。
3 Cpu(s): 这一行描述了 CPU 正在进行的活动的特性。
  0.7%us 0.7% 的 CPU 被用于用户进程。这意味着进程在内核之外。
  1.0%sy 1.0%的 CPU 时间被用于系统(内核)进程。
  0.0%ni 0.0%的 CPU 时间被用于"nice"(低优先级)进程。
  98.3%id 98.3%的 CPU 时间是空闲的。
  0.0%wa 0.0%的 CPU 时间来等待 I/O。
4 Mem: 展示物理内存的使用情况。
5 Swap: 展示交换分区(虚拟内存)的使用情况。

The top program accepts a number of keyboard commands. The two most interesting are h, which displays the program’s help screen, and q, which quits top.

top 程序接受一系列从键盘输入的命令。两个最有趣的命令是 h 和 q。h,显示程序的帮助屏幕,q, 退出 top 程序。

Both major desktop environments provide graphical applications that display information similar to top (in much the same way that Task Manager in Windows works), but I find that top is better than the graphical versions because it is faster and it consumes far fewer system resources. After all, our system monitor program shouldn’t be the source of the system slowdown that we are trying to track.

两个主要的桌面环境都提供了图形化应用程序,来显示与 top 程序相似的信息 (和 Windows 中的任务管理器差别不多),但是我觉得 top 程序要好于图形化的版本, 因为它运行速度快,并且消费很少的系统资源。毕竟,我们的系统监测程序不能成为 我们试图追踪的系统怠工的原因。

把一个进程放置到后台(执行)

Let’s say we wanted to get the shell prompt back without terminating the xlogo program. We’ll do this by placing the program in the background. Think of the terminal as having a foreground (with stuff visible on the surface like the shell prompt) and a background (with hidden stuff behind the surface.) To launch a program so that it is immediately placed in the background, we follow the command with an- “&” character:

假如说我们想让 shell 提示符返回,却不终止 xlogo 程序。我们可以把 这个程序放到后台(background)执行。把终端想象是一个有前台(包含在表层可见的事物,像 shell 提示符) 和后台(包含表层之下的隐藏的事物)(的设备)。为了启动一个程序并让它立即在后台 运行,我们在程序命令之后,加上”&”字符:

[me@linuxbox ~]$ xlogo &
[1] 28236
[me@linuxbox ~]$

After entering the command, the xlogo window appeared and the shell prompt returned, but some funny numbers were printed too. This message is part of a shell feature called job control. With this message, the shell is telling us that we have started job number 1 (“[1]”) and that it has PID 28236. If we run ps, we can see our process:

执行命令之后,这个 xlogo 窗口出现,并且 shell 提示符返回,同时打印一些有趣的数字。 这条信息是 shell 特性的一部分,叫做任务控制 (job control)。通过这条信息,shell 告诉我们,已经启动了 任务号(job number)为1(“[1]”),PID 为28236的程序。如果我们运行 ps 命令,可以看到我们的进程:

[me@linuxbox ~]$ ps
  PID TTY         TIME   CMD
10603 pts/1   00:00:00   bash
28236 pts/1   00:00:00   xlogo
28239 pts/1   00:00:00   ps

The shell’s job control facility also gives us a way to list the jobs that are have been launched from our terminal. Using the jobs command, we can see this list:

shell 的任务控制功能给出了一种列出从我们终端中启动了的任务的方法。执行 jobs 命令,我们可以看到这个输出列表:

[me@linuxbox ~]$ jobs
[1]+ Running            xlogo &

The results show that we have one job, numbered “1”, that it is running, and that the command was xlogo &.

结果显示我们有一个任务,编号为“1”,它正在运行,并且这个任务的命令是 xlogo &。

进程返回到前台

A process in the background is immune from keyboard input, including any attempt interrupt it with a Ctrl-c. To return a process to the foreground, use the fg command, this way:

一个在后台运行的进程对一切来自键盘的输入都免疫,也不能用 Ctrl-c 来中断它。 为了让一个进程返回前台 (foreground),这样使用 fg 命令:

[me@linuxbox ~]$ jobs
[1]+ Running        xlogo &
[me@linuxbox ~]$ fg %1
xlogo

The command fg followed by a percent sign and the job number (called a jobspec) does the trick. If we only have one background job, the jobspec is optional. To terminate xlogo, type Ctrl-c.

fg 命令之后,跟随着一个百分号和任务序号(叫做 jobspec,如此处的%1)就可以了。如果我们只有一个后台任务,那么 jobspec(job specification) 是可有可无的。输入 Ctrl-c 来终止 xlogo 程序。

停止一个进程

Sometimes we’ll want to stop a process without terminating it. This is often done to allow a foreground process to be moved to the background. To stop a foreground process, type Ctrl-z. Let’s try it. At the command prompt, type xlogo, the Enter key, then Ctrl-z:

有时候,我们想要停止一个进程,而不是终止它。我们这么做通常是为了允许前台进程被移动到后台。 输入 Ctrl-z,可以停止一个前台进程。让我们试一下。在命令提示符下,执行 xlogo 命令, 然后输入 Ctrl-z:

[me@linuxbox ~]$ xlogo
[1]+ Stopped                 xlogo
[me@linuxbox ~]$

After stopping xlogo, we can verify that the program has stopped by attempting to resize the xlogo window. We will see that it appears quite dead. We can either restore the program to the foreground, using the fg command, or move the program to the background with the bg command:

停止 xlogo 程序之后,通过调整 xlogo 的窗口大小,我们可以证实这个程序已经停止了。 它看起来像死掉了一样。使用 fg 命令,可以恢复程序到前台运行,或者用 bg 命令把程序移到后台。

[me@linuxbox ~]$ bg %1
[1]+ xlogo &
[me@linuxbox ~]$

As with the fg command, the jobspec is optional if there is only one job.

和 fg 命令一样,如果只有一个任务的话,jobspec 参数是可选的。

Moving a process from the foreground to the background is handy if we launch a graphical program from the command, but forget to place it in the background by appending the trailing “&”.

如果我们从命令行启动一个图形程序,但是忘了在命令后加字符 “&”, 将一个进程从前台移动到后台也是很方便的。

Why would you want to launch a graphical program from the command line? There are two reasons. First, the program you wish to run might not be listed on the window manager’s menus (such as xlogo). Secondly, by launching a program from the command line, you might be able to see error messages that would otherwise be invisible if the program were launched graphically. Sometimes, a program will fail to start up when launched from the graphical menu. By launching it from the command line instead, we may see an error message that will reveal the problem. Also, some graphical programs have many interesting and useful command line options.

为什么要从命令行启动一个图形界面程序呢?有两个原因。第一个,你想要启动的程序,可能 没有在窗口管理器的菜单中列出来(比方说 xlogo)。第二个,从命令行启动一个程序, 你能够看到一些错误信息,如果从图形界面中运行程序的话,这些信息是不可见的。有时候, 一个程序不能从图形界面菜单中启动。通过从命令行中启动它,我们可能会看到 能揭示问题的错误信息。一些图形界面程序还有许多有意思并且有用的命令行选项。

检查环境变量

We can use either the set builtin in bash or the printenv program to see what is stored in the environment. The set command will show both the shell and environment variables, while printenv will only display the latter. Since the list of environment contents will be fairly long, it is best to pipe the output of either command into less:

我们可以用 bash 的内建命令 set,或者是 printenv 程序来查看环境变量。set 命令可以 显示 shell 或环境变量,而 printenv 只是显示环境变量。因为环境变量列表比较长,最好 把每个命令的输出通过管道传递给 less 来阅读:

[me@linuxbox ~]$ printenv | less

Doing so, we should get something that looks like this:

执行以上命令之后,我们应该能得到类似以下内容:

KDE_MULTIHEAD=false
SSH_AGENT_PID=6666
HOSTNAME=linuxbox
GPG_AGENT_INFO=/tmp/gpg-PdOt7g/S.gpg-agent:6689:1
SHELL=/bin/bash
TERM=xterm
XDG_MENU_PREFIX=kde-
HISTSIZE=1000
XDG_SESSION_COOKIE=6d7b05c65846c3eaf3101b0046bd2b00-1208521990.996705
-1177056199
GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/home/me/.gtkrc-2.0:/home/me/.kde/sh
are/config/gtkrc-2.0
GTK_RC_FILES=/etc/gtk/gtkrc:/home/me/.gtkrc:/home/me/.kde/share/confi
g/gtkrc
GS_LIB=/home/me/.fonts
WINDOWID=29360136
QTDIR=/usr/lib/qt-3.3
QTINC=/usr/lib/qt-3.3/include
KDE_FULL_SESSION=true
USER=me
LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01
:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe:

What we see is a list of environment variables and their values. For example, we see a variable called USER, which contains the value “me”. The printenv command can also list the value of a specific variable:

我们所看到的是环境变量及其数值的列表。例如,我们看到一个叫做 USER 的变量,这个变量值是 “me”。printenv 命令也能够列出特定变量的数值:

[me@linuxbox ~]$ printenv USER
me

The set command, when used without options or arguments, will display both the shell and environment variables, as well as any defined shell functions. Unlike printenv, its output is courteously sorted in alphabetical order:

当使用没有带选项和参数的 set 命令时,shell 变量,环境变量,和定义的 shell 函数 都会被显示。不同于 printenv 命令,set 命令的输出很友好地按照首字母顺序排列:

[me@linuxbox ~]$ set | less

It is also possible to view the contents of a variable using the echo command, like this:

也可以通过 echo 命令来查看一个变量的内容,像这样:

[me@linuxbox ~]$ echo $HOME
/home/me

One element of the environment that neither set nor printenv displays is aliases. To see them, enter the alias command without arguments:

别名无法通过使用 set 或 printenv 来查看。 用不带参数的 alias 来查看别名:

[me@linuxbox ~]$ alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'


一些有趣的环境变量

The environment contains quite a few variables, and though your environment may differ from the one presented here, you will likely see the following variables in your environment:

shell 环境中包含相当多的变量。虽然你的 shell 环境可能与这里的不同,你可能会看到 以下的环境变量:

Table 12-1: Environment Variables
VariableContents
DISPLAY The name of your display if you are running a graphical environment. Usually this is ":0", meaning the first display generated by the X server.
EDITOR The name of the program to be used for text editing.
SHELL The name of your shell program.
HOME The pathname of your home directory.
LANG Defines the character set and collation order of your language.
OLD_PWD The previous working directory.
PAGER The name of the program to be used for paging output. This is often set to /usr/bin/less.
PATH A colon-separated list of directories that are searched when you enter the name of a executable program.
PS1 Prompt String 1. This defines the contents of your shell prompt. As we will later see, this can be extensively customized.
PWD The current working directory.
TERM The name of your terminal type. Unix-like systems support many terminal protocols; this variable sets the protocol to be used with your terminal emulator.
TZ Specifies your timezone. Most Unix-like systems maintain the computer's internal clock in Coordinated Universal Time (UTC) and then displays the local time by applying an offset specified by this variable.
USER Your user name.
表12-1: 环境变量
变量内容
DISPLAY 如果你正在运行图形界面环境,那么这个变量就是你显示器的名字。通常,它是 ":0", 意思是由 X 产生的第一个显示器。
EDITOR 文本编辑器的名字。
SHELL shell 程序的名字。
HOME 用户家目录。
LANG 定义了字符集以及语言编码方式。
OLD_PWD 先前的工作目录。
PAGER 页输出程序的名字。这经常设置为/usr/bin/less。
PATH 由冒号分开的目录列表,当你输入可执行程序名后,会搜索这个目录列表。
PS1 Prompt String 1. 这个定义了你的 shell 提示符的内容。随后我们可以看到,这个变量 内容可以全面地定制。
PWD 当前工作目录。
TERM 终端类型名。类 Unix 的系统支持许多终端协议;这个变量设置你的终端仿真器所用的协议。
TZ 指定你所在的时区。大多数类 Unix 的系统按照协调时间时 (UTC) 来维护计算机内部的时钟 ,然后应用一个由这个变量指定的偏差来显示本地时间。
USER 你的用户名

Don’t worry if some of these values are missing. They vary by distribution.

如果缺失了一些变量,不要担心,这些变量会因发行版本的不同而不同。

如何建立 shell 环境?

When we log on to the system, the bash program starts, and reads a series of configuration scripts called startup files, which define the default environment shared by all users. This is followed by more startup files in our home directory that define our personal environment. The exact sequence depends on the type of shell session being started. There are two kinds: a login shell session and a non-login shell session.

当我们登录系统后, bash 程序启动,并且会读取一系列称为启动文件的配置脚本, 这些文件定义了默认的可供所有用户共享的 shell 环境。然后是读取更多位于我们自己家目录中 的启动文件,这些启动文件定义了用户个人的 shell 环境。确切的启动顺序依赖于要运行的 shell 会话 类型。有两种 shell 会话类型:一个是登录 shell 会话,另一个是非登录 shell 会话。

A login shell session is one in which we are prompted for our user name and password; when we start a virtual console session, for example. A non-login shell session typically occurs when we launch a terminal session in the GUI.

登录 shell 会话会在其中提示用户输入用户名和密码;例如,我们启动一个虚拟控制台会话。 非登录 shell 会话通常当我们在 GUI 下启动终端会话时出现。

Login shells read one or more startup files as shown in Table 12-2:

登录 shell 会读取一个或多个启动文件,正如表12-2所示:

Table 12-2: Startup Files For Login Shell Sessions
FileContents
/etc/profile A global configuration script that applies to all users.
~/.bash_profile A user's personal startup file. Can be used to extend or override settings in the global configuration script.
~/.bash_login If ~/.bash_profile is not found, bash attempts to read this script.
~/.profile If neither ~/.bash_profile nor ~/.bash_login is found, bash attempts to read this file. This is the default in Debian-based distributions, such as Ubuntu.
表12-2: 登录 shell 会话的启动文件
文件内容
/etc/profile 应用于所有用户的全局配置脚本。
~/.bash_profile 用户个人的启动文件。可以用来扩展或重写全局配置脚本中的设置。
~/.bash_login 如果文件 ~/.bash_profile 没有找到,bash 会尝试读取这个脚本。
~/.profile 如果文件 ~/.bash_profile 或文件 ~/.bash_login 都没有找到,bash 会试图读取这个文件。 这是基于 Debian 发行版的默认设置,比方说 Ubuntu。

Non-login shell sessions read the following startup files:

非登录 shell 会话会读取以下启动文件:

Table 12-3: Startup Files For Non-Login Shell Sessions
FileContents
/etc/bash.bashrc A global configuration script that applies to all users.
~/.bashrc A user's personal startup file. Can be used to extend or override settings in the global configuration script.
表12-3: 非登录 shell 会话的启动文件
文件内容
/etc/bash.bashrc 应用于所有用户的全局配置文件。
~/.bashrc 用户个人的启动文件。可以用来扩展或重写全局配置脚本中的设置。

In addition to reading the startup files above, non-login shells also inherit the environment from their parent process, usually a login shell.

除了读取以上启动文件之外,非登录 shell 会话也会继承它们父进程的环境设置,通常是一个登录 shell。

Take a look at your system and see which of these startup files you have. Remember— since most of the filenames listed above start with a period (meaning that they are hidden), you will need to use the “-a” option when using ls.

浏览一下你的系统,看一看系统中有哪些启动文件。记住-因为上面列出的大多数文件名都以圆点开头 (意味着它们是隐藏文件),你需要使用带”-a”选项的 ls 命令。

The ~/.bashrc file is probably the most important startup file from the ordinary user’s point of view, since it is almost always read. Non-login shells read it by default and most startup files for login shells are written in such a way as to read the ~/.bashrc file as well.

在普通用户看来,文件 ~/.bashrc 可能是最重要的启动文件,因为它几乎总是被读取。非登录 shell 默认 会读取它,并且大多数登录 shell 的启动文件会以能读取 ~/.bashrc 文件的方式来书写。

一个启动文件的内容

If we take a look inside a typical .bash_profile (taken from a CentOS 4 system), it looks something like this:

如果我们看一下典型的 .bash_profile 文件(来自于 CentOS 4 系统),它看起来像这样:

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH

Lines that begin with a “#” are comments and are not read by the shell. These are there for human readability. The first interesting thing occurs on the fourth line, with the following code:

以”#”开头的行是注释,shell 不会读取它们。它们在那里是为了方便人们阅读。第一件有趣的事情 发生在第四行,伴随着以下代码:

if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

This is called an if compound command, which we will cover fully when we get to shell scripting in Part 5, but for now we will translate:

这叫做一个 if 复合命令,我们将会在第五部分详细地介绍它,现在我们对它翻译一下:

If the file ~/.bashrc exists, then
read the ~/.bashrc file.

We can see that this bit of code is how a login shell gets the contents of .bashrc. The next thing in our startup file has to do with the PATH variable.

我们可以看到这一小段代码就是一个登录 shell 得到 .bashrc 文件内容的方式。在我们启动文件中, 下一件有趣的事与 PATH 变量有关系。

Ever wonder how the shell knows where to find commands when we enter them on the command line? For example, when we enter ls, the shell does not search the entire computer to find /bin/ls (the full pathname of the ls command), rather, it searches a list of directories that are contained in the PATH variable.

是否曾经对 shell 怎样知道在哪里找到我们在命令行中输入的命令感到迷惑?例如,当我们输入 ls 后, shell 不会查找整个计算机系统来找到 /bin/ls(ls 命令的全路径名),相反,它查找一个目录列表, 这些目录包含在 PATH 变量中。

The PATH variable is often (but not always, depending on the distribution) set by the /etc/profile startup file and with this code:

PATH 变量经常(但不总是,依赖于发行版)在 /etc/profile 启动文件中设置,通过这些代码:

PATH=$PATH:$HOME/bin

PATH is modified to add the directory $HOME/bin to the end of the list. This is an example of parameter expansion, which we touched on in Chapter 8. To demonstrate how this works, try the following:

修改 PATH 变量,添加目录 $HOME/bin 到目录列表的末尾。这是一个参数展开的实例, 参数展开我们在第八章中提到过。为了说明这是怎样工作的,试试下面的例子:

[me@linuxbox ~]$ foo="This is some"
[me@linuxbox ~]$ echo $foo
This is some
[me@linuxbox ~]$ foo="$foo text."
[me@linuxbox ~]$ echo $foo
This is some text.

Using this technique, we can append text to the end of a variable’s contents. By adding the string $HOME/bin to the end of the PATH variable’s contents, the directory $HOME/bin is added to the list of directories searched when a command is entered. This means that when we want to create a directory within our home directory for storing our own private programs, the shell is ready to accommodate us. All we have to do is call it bin, and we’re ready to go.

使用这种技巧,我们可以把文本附加到一个变量值的末尾。通过添加字符串 $HOME/bin 到 PATH 变量值 的末尾,则目录 $HOME/bin 就添加到了命令搜索目录列表中。这意味着当我们想要在自己的家目录下, 创建一个目录来存储我们自己的私人程序时,shell 已经给我们准备好了。我们所要做的事就是 把创建的目录叫做 bin,赶快行动吧。

Note: Many distributions provide this PATH setting by default. Some Debian based distributions, such as Ubuntu, test for the existence of the ~/bin directory at login, and dynamically add it to the PATH variable if the directory is found.

注意:很多发行版默认地提供了这个 PATH 设置。一些基于 Debian 的发行版,例如 Ubuntu,在登录 的时候,会检测目录 ~/bin 是否存在,若找到目录则把它动态地加到 PATH 变量中。

Lastly, we have:

最后,有下面一行代码:

export PATH

The export command tells the shell to make the contents of PATH available to child processes of this shell.

这个 export 命令告诉 shell 让这个 shell 的子进程可以使用 PATH 变量的内容。

激活我们的修改

The changes we have made to our .bashrc will not take affect until we close our terminal session and start a new one, since the .bashrc file is only read at the beginning of a session. However, we can force bash to re-read the modified .bashrc file with the following command:

我们对于文件 .bashrc 的修改不会生效,直到我们关闭终端会话,再重新启动一个新的会话, 因为 .bashrc 文件只是在刚开始启动终端会话时读取。然而,我们可以强迫 bash 重新读取修改过的 .bashrc 文件,使用下面的命令:

[me@linuxbox ~]$ source .bashrc

After doing this, we should be able to see the effect of our changes. Try out one of the new aliases:

运行上面命令之后,我们就应该能够看到所做修改的效果了。试试其中一个新的别名:

[me@linuxbox ~]$ ll



编写第一个 Shell 脚本

什么是 Shell 脚本?

In the simplest terms, a shell script is a file containing a series of commands. The shell reads this file and carries out the commands as though they have been entered directly on the command line.

最简单的解释,一个 shell 脚本就是一个包含一系列命令的文件。shell 读取这个文件,然后执行 文件中的所有命令,就好像这些命令已经直接被输入到了命令行中一样。

The shell is somewhat unique, in that it is both a powerful command line interface to the system and a scripting language interpreter. As we will see, most of the things that can be done on the command line can be done in scripts, and most of the things that can be done in scripts can be done on the command line.

Shell 有些独特,因为它不仅是一个功能强大的命令行接口,也是一个脚本语言解释器。我们将会看到, 大多数能够在命令行中完成的任务也能够用脚本来实现,同样地,大多数能用脚本实现的操作也能够 在命令行中完成。

We have covered many shell features, but we have focused on those features most often used directly on the command line. The shell also provides a set of features usually (but not always) used when writing programs.

虽然我们已经介绍了许多 shell 功能,但只是集中于那些经常直接在命令行中使用的功能。 Shell 也提供了一些通常(但不总是)在编写程序时才使用的功能。

怎样编写一个 Shell 脚本

To successfully create and run a shell script, we need to do three things:

为了成功地创建和运行一个 shell 脚本,我们需要做三件事情:

  1. Write a script. Shell scripts are ordinary text files. So we need a text editor to write them. The best text editors will provide syntax highlighting, allowing us to see a color-coded view of the elements of the script. Syntax highlighting will help us spot certain kinds of common errors. vim, gedit, kate, and many other editors are good candidates for writing scripts.

  2. Make the script executable. The system is rather fussy about not letting any old text file be treated as a program, and for good reason! We need to set the script file’s permissions to allow execution.

  3. Put the script somewhere the shell can find it. The shell automatically searches certain directories for executable files when no explicit pathname is specified. For maximum convenience, we will place our scripts in these directories.

  1. 编写一个脚本。 Shell 脚本就是普通的文本文件。所以我们需要一个文本编辑器来书写它们。最好的文本 编辑器都会支持语法高亮,这样我们就能够看到一个脚本关键字的彩色编码视图。语法高亮会帮助我们查看某种常见 错误。为了编写脚本文件,vim,gedit,kate,和许多其它编辑器都是不错的候选者。

  2. 使脚本文件可执行。 系统会相当挑剔不允许任何旧的文本文件被看作是一个程序,并且有充分的理由! 所以我们需要设置脚本文件的权限来允许其可执行。

  3. 把脚本放置到 shell 能够找到的地方。 当没有指定可执行文件明确的路径名时,shell 会自动地搜索某些目录, 来查找此可执行文件。为了最大程度的方便,我们会把脚本放到这些目录当中。

脚本文件格式

In keeping with programming tradition, we’ll create a “hello world” program to demonstrate an extremely simple script. So let’s fire up our text editors and enter the following script:

为了保持编程传统,我们将创建一个 “hello world” 程序来说明一个极端简单的脚本。所以让我们启动 我们的文本编辑器,然后输入以下脚本:

#!/bin/bash
# This is our first script.
echo 'Hello World!'

The last line of our script is pretty familiar, just an echo command with a string argument. The second line is also familiar. It looks like a comment that we have seen used in many of the configuration files we have examined and edited. One thing about comments in shell scripts is that they may also appear at the end of lines, like so:

对于脚本中的最后一行,我们应该是相当的熟悉,仅仅是一个带有一个字符串参数的 echo 命令。 对于第二行也很熟悉。它看起来像一个注释,我们已经在许多我们检查和编辑过的配置文件中 看到过。关于 shell 脚本中的注释,它们也可以出现在文本行的末尾,像这样:

echo 'Hello World!' # This is a comment too

Everything from the # symbol onward on the line is ignored.

文本行中,# 符号之后的所有字符都会被忽略。

Like many things, this works on the command line, too:

类似于许多命令,这也在命令行中起作用:

[me@linuxbox ~]$ echo 'Hello World!' # This is a comment too
Hello World!

Though comments are of little use on the command line, they will work.

虽然很少在命令行中使用注释,但它们也能起作用。

The first line of our script is a little mysterious. It looks like it should be a comment, since it starts with #, but it looks too purposeful to be just that. The #! character sequence is, in fact, a special construct called a shebang. The shebang is used to tell the system the name of the interpreter that should be used to execute the script that follows. Every shell script should include this as its first line.

我们脚本中的第一行文本有点儿神秘。它看起来它应该是一条注释,因为它起始于一个#符号,但是 它看起来太有意义,以至于不仅仅是注释。事实上,这个#!字符序列是一种特殊的结构叫做 shebang。 这个 shebang 被用来告诉操作系统将执行此脚本所用的解释器的名字。每个 shell 脚本都应该把这一文本行 作为它的第一行。

Let’s save our script file as hello_world.

让我们把此脚本文件保存为 hello_world。

可执行权限

The next thing we have to do is make our script executable. This is easily done using chmod:

下一步我们要做的事情是让我们的脚本可执行。使用 chmod 命令,这很容易做到:

[me@linuxbox ~]$ ls -l hello_world
-rw-r--r-- 1  me    me      63  2009-03-07 10:10 hello_world
[me@linuxbox ~]$ chmod 755 hello_world
[me@linuxbox ~]$ ls -l hello_world
-rwxr-xr-x 1  me    me      63  2009-03-07 10:10 hello_world

There are two common permission settings for scripts; 755 for scripts that everyone can execute, and 700 for scripts that only the owner can execute. Note that scripts must be readable in order to be executed.

对于脚本文件,有两个常见的权限设置;权限为755的脚本,则每个人都能执行,和权限为700的 脚本,只有文件所有者能够执行。注意为了能够执行脚本,脚本必须是可读的。

Configuring vim For Script Writing

为书写脚本配置 vim

The vim text editor has many, many configuration settings. There are several common options that can facilitate script writing:

这个 vim 文本编辑器有许多许多的配置设置。有几个常见的选项能够有助于脚本书写:

:syntax on

turns on syntax highlighting. With this setting, different elements of shell syntax will be displayed in different colors when viewing a script. This is helpful for identifying certain kinds of programming errors. It looks cool, too. Note that for this feature to work, you must have a complete version of vim installed, and the file you are editing must have a shebang indicating the file is a shell script. If you have difficulty with the command above, try :set syntax=sh instead.

打开语法高亮。通过这个设置,当查看脚本的时候,不同的 shell 语法元素会以不同的颜色 显示。这对于识别某些编程错误很有帮助。并且它看起来也很酷。注意为了这个功能起作用,你 必须安装了一个完整的 vim 版本,并且你编辑的文件必须有一个 shebang,来说明这个文件是 一个 shell 脚本。如果对于上面的命令,你遇到了困难,试试 :set syntax=sh。

:set hlsearch

turns on the option to highlight search results. Say we search for the word “echo.” With this option on, each instance of the word will be highlighted.

打开这个选项是为了高亮查找结果。比如说我们查找单词“echo”。通过设置这个选项,这个 单词的每个实例会高亮显示。

:set tabstop=4

sets the number of columns occupied by a tab character. The default is eight columns. Setting the value to four (which is a common practice) allows long lines to fit more easily on the screen.

设置一个 tab 字符所占据的列数。默认是8列。把这个值设置为4(一种常见做法), 从而让长文本行更容易适应屏幕。

:set autoindent

turns on the “auto indent” feature. This causes vim to indent a new line the same amount as the line just typed. This speeds up typing on many kinds of programming constructs. To stop indentation, type Ctrl-d.

打开 “auto indent” 功能。这导致 vim 能对新的文本行缩进与刚输入的文本行相同的列数。 对于许多编程结构来说,这就加速了输入。停止缩进,输入 Ctrl-d。

These changes can be made permanent by adding these commands (without the leading colon characters) to your ~/.vimrc file.

通过把这些命令(没有开头的冒号字符)添加到你的 ~/.vimrc 文件中,这些改动会永久生效。

原文地址:https://www.cnblogs.com/PrayG/p/10966685.html