到目前为止,我们已经看到了一系列神秘的命令,每个命令都有自己的神秘选项和参数。在本章中,我们将尝试消除一些神秘感,甚至创建我们自己的命令。本章介绍的命令包括:
type
—— 指示如何解释命令名称
which
—— 显示可执行文件的位置(物理路径)
help
—— 获取shell内置的帮助
man
—— 显示命令的手册页(manual page)
apropos
—— 显示相应命令的列表
命令名或单行手册页描述中包含指定字符串的,都会显示出来
info
—— 显示命令的信息条目
whatis
—— 显示单行手册页面描述
alias
—— 为命令创建别名
第五章:使用命令命令究竟是什么?识别命令type
—— 显示命令类型which
—— 显示可执行文件的位置获取命令文档help
—— 获取shell内置的帮助--help
—— 显示使用信息man
—— 显示程序的手册页apropos
—— 显示适当的命令whatis
—— 显示单行手册页面说明最残忍的手册页info
—— 显示程序的信息条目README和其他程序文档文件使用 alias
创建我们自己的命令总结
命令可以是四种不同的东西之一:
一个可执行程序。
就像我们在 /usr/bin 中看到的所有文件一样。在这个类别中,程序可以是编译的二进制文件(compiled binaries),如用C和C++编写的程序;也可以是用shell、Perl、Python、Ruby等脚本语言编写的程序。
内置于shell本身的命令。
bash
支持许多内部称为shell内置(shell builtins)的命令。例如,cd
命令是一个shell内置的。
shell函数。
Shell函数是集成到环境(environment)中的微型Shell脚本。我们将在后面的章节中介绍配置环境和编写shell函数,但现在,请注意它们的存在。
别名。
别名是我们可以自己定义的命令,由其他命令构建而成。
确切地知道正在使用四种命令中的哪一种通常很有用,Linux提供了几种方法来找出答案。
type
—— 显示命令类型type
命令是一个内置的shell,它显示给定特定命令名的shell将执行的命令类型。其工作形式如下:
type command
其中 command 是我们要检查的命令的名称。以下是一些示例:
xxxxxxxxxx
[me@linuxbox ~]$ type type
type is a shell builtin
[me@linuxbox ~]$ type ls
ls is aliased to `ls --color=auto'
[me@linuxbox ~]$ type cp
cp is /usr/bin/cp
这里我们看到了三个不同命令的结果。请注意 ls
命令(取自Fedora系统),以及 ls
命令实际上是 ls
命令的别名,并添加了 --color=tty
选项。现在我们知道为什么ls的输出是彩色的了!
【debian中ls
是 ls --color=auto
的别名。ls --color
的值可以是 always
(或写成 yes
、force
)、never
(或写成no
、none
)、auto
(或写成tty
、if-tty
)】
which
—— 显示可执行文件的位置有时系统上安装了多个版本的可执行程序。虽然这在桌面系统上并不常见,但在大型服务器上并不罕见。要确定给定可执行文件的确切位置,请使用哪个命令。
xxxxxxxxxx
[me@linuxbox ~]$ which ls
/usr/bin/ls
which
只适用于可执行程序,而不适用于替代实际可执行程序的内置程序或别名。当我们尝试在内置的shell上使用 which
时,例如 cd
,我们要么没有响应,要么收到错误消息:
xxxxxxxxxx
[me@linuxbox ~]$ which cd
/usr/bin/which: no cd in (/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games)
这个响应是一种说【dommand not found】的花哨方式。
【debian无显示,FreeBSD显示 /usr/bin/cd 】
help
—— 获取shell内置的帮助bash为每个shell内置都提供了一个内置的帮助工具。要使用它,请键入 help
,后跟内置shell的名称。以下是一个示例:
xxxxxxxxxx
[me@linuxbox ~]$ help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
Change the current directory to DIR. The default DIR is the value of the HOME shell variable.
The variable CDPATH defines the search path for the directory containing DIR. Alternative directory names in CDPATH are separated by a colon (:). A null directory name is the same as the current directory. If DIR begins with a slash (/), then CDPATH is not used.
If the directory is not found, and the shell option `cdable_vars' is set, the word is assumed to be a variable name. If that variable has a value, its value is used for DIR.
Options:
-L force symbolic links to be followed: resolve symbolic links in DIR after processing instances of `..'
-P use the physical directory structure without following symbolic links: resolve symbolic links in DIR before processing instances of `..'
-e if the -P option is supplied, and the current working directory cannot be determined successfully, exit with a non-zero status
-@ on systems that support it, present a file with extended attributes as a directory containing the file attributes
The default is to follow symbolic links, as if `-L' were specified. `..' is processed by removing the immediately previous pathname component back to a slash or the beginning of DIR.
Exit Status:
Returns 0 if the directory is changed, and if $PWD is set successfully when -P is used; non-zero otherwise.
关于符号的说明:当方括号出现在命令语法的描述中时,它们表示可选项。竖线字符表示互斥项目。在上述cd命令的情况下:
cd [ -L | [-P [-e]]] [dir]
这种表示法表示,命令 cd
后面可以可选地跟有 -L
或 -P
,此外,如果指定了 -P
选项,则还可以包含 -e
选项,后跟可选参数 dir
。
虽然 cd
命令的 help
输出简洁准确,但它绝不是教程,正如我们所看到的,它似乎还提到了很多我们还没有讨论过的事情!别担心。我们会到达那里。
有用提示:通过使用带有 -m
选项的 help
命令, help
将以另一种格式显示其输出。
--help
—— 显示使用信息许多可执行程序支持 --help
选项,该选项显示命令支持的语法和选项的描述。例如:
xxxxxxxxxx
[me@linuxbox ~]$ mkdir --help
Usage: mkdir [OPTION] DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.
-Z, --context=CONTEXT (SELinux) set security context to CONTEXTMandatory arguments to long options are mandatory for short options too.
-m, --mode=MODE set file mode (as in chmod), not a=rwx – umask
-p, --parents no error if existing, make parent directories as needed
-v, --verbose print a message for each created directory
--help display this help and exit
--version output version information and exit
Report bugs to <bug-coreutils@gnu.org>.
有些程序不支持 --help
选项,但无论如何都要尝试一下。通常,它会导致一条错误消息,显示相同的使用信息。
man
—— 显示程序的手册页大多数用于命令行的可执行程序都提供了一份正式的文档,称为手册(manual)或手册页(man page)。一个名为man
的特殊分页程序用于查看它们。它的使用方式如下:
man program
其中 program 是要查看的命令的名称。
手册页的格式略有不同,但通常包含以下内容:
然而,手册页通常不包含示例,仅供参考,而非教程。例如,让我们尝试查看ls
命令的手册页:
xxxxxxxxxx
[me@linuxbox ~]$ man ls
在大多数Linux系统上,man
使用less
命令来显示手册页,因此所有熟悉的 less
命令在显示页面时都能工作。
man
显示的“手册”分为几个部分,不仅涵盖用户命令,还涵盖系统管理命令、编程接口、文件格式等。下表描述了手册的布局:
章节 | 内容 |
---|---|
1 | 用户命令 |
2 | 内核系统调用的编程接口 |
3 | C库的编程接口 |
4 | 设备节点和驱动程序等特殊文件 |
5 | 文件格式 |
6 | 游戏和娱乐,如屏幕保护程序 |
7 | 各种各样的 |
8 | 系统管理命令 |
有时我们需要参考手册的特定部分来找到我们要找的东西。如果我们正在寻找一种也是命令名称的文件格式,这一点尤其正确。如果不指定节号,我们将始终得到匹配的第一个实例,可能是在节1中。要指定节号,我们使用man,如下所示:
man section search_term
下面是一个示例:
xxxxxxxxxx
[me@linuxbox ~]$ man 5 passwd
这将显示描述 /etc/passwd 文件的文件格式的手册页。
apropos
—— 显示适当的命令还可以根据搜索词在手册页列表中搜索可能的匹配项。它很粗糙,但有时很有用。以下是使用搜索词 partition 搜索手册页的示例:
xxxxxxxxxx
[me@linuxbox ~]$ apropos partition
addpart (8) - simple wrapper around the "add partition"...
all-swaps (7) - event signalling that all swap partitions...
cfdisk (8) - display or manipulate disk partition table
cgdisk (8) - Curses-based GUID partition table (GPT)...
delpart (8) - simple wrapper around the "del partition"...
fdisk (8) - manipulate disk partition table
fixparts (8) - MBR partition table repair utility
gdisk (8) - Interactive GUID partition table (GPT)...
mpartition (1) - partition an MSDOS hard disk
partprobe (8) - inform the OS of partition table changes
partx (8) - tell the Linux kernel about the presence...
resizepart (8) - simple wrapper around the "resize partition...
sfdisk (8) - partition table manipulator for Linux
sgdisk (8) - Command-line GUID partition table (GPT)...
每行输出中的第一个字段是手册页的名称,第二个字段显示该部分。请注意,带有 -k
选项的 man
命令执行的功能与 apropos
相同。
whatis
—— 显示单行手册页面说明whatis
程序显示与指定关键字匹配的手册页的名称和单行描述:
xxxxxxxxxx
[me@linuxbox ~]$ whatis ls
ls (1) - list directory contents
正如我们所看到的,Linux和其他类Unix系统提供的手册页是作为参考文档,而不是教程。许多手册页很难阅读,但我认为难度的大奖必须颁给bash的手册页。当我为这本书做研究时,我仔细审查了 bash
手册页,以确保我涵盖了它的大部分主题。打印时,它有80多页长,非常密集,它的结构对新用户来说绝对没有意义。
另一方面,它非常准确和简洁,而且非常完整。所以,如果你敢的话,看看它,期待有一天你能读到它,这一切都有意义。
info
—— 显示程序的信息条目GNU工程为他们的程序提供了一种替代手册页的方法,称为 info
。info手册与一个名为 info
的阅读器程序一起显示。信息页面与网页非常相似。以下是一个示例:
xxxxxxxxxx
File: coreutils.info, Node: ls invocation, Next: dir invocation, Up: Directory listing
10.1 `ls': List directory contents
==================================
The 'ls' program lists information about files (of any type, including directories). Options and file arguments can be intermixed arbitrarily, as usual.
For non-option command-line arguments that are directories, by default 'ls' lists the contents of directories, not recursively, and omitting files with names beginning with '.'. For other non-option arguments, by default 'ls' lists just the filename. If no non-option argument is specified, 'ls' operates on the current directory, acting as if it had been invoked with a single argument of '.'.
By default, the output is sorted alphabetically, according to the
--zz-Info: (coreutils.info.gz)ls invocation, 63 lines --Top----------
info
程序读取 info files ,这些文件是树形结构,分为单个节点,每个节点包含一个主题。信息文件包含可以将阅读器从一个节点移动到另一个节点的超链接。超链接可以通过其前导星号来识别,将光标放在超链接上并按Enter键即可激活。
要调用 info
,请键入 info
,然后可选地键入程序名称。下表描述了在显示信息页面时用于控制阅读器的命令。
命令 | 动作 |
---|---|
? | 显示命令帮助 |
PgUp 或 Backspace | 显示上一页 |
PgDn 或 Space | 显示下一页 |
n | Next——显示下一个节点 |
p | Previous——显示上一个节点 |
u | Up——显示当前显示节点的父节点,通常是菜单 |
Enter | 按照光标位置的超链接进行操作 |
q | 退出 |
到目前为止,我们讨论的大多数命令行程序都是GNU项目的 coreutils 包的一部分,因此键入以下内容:
xxxxxxxxxx
[me@linuxbox ~]$ info coreutils
将显示一个菜单页面,其中包含指向 coreutils 包中包含的每个程序的超链接。
我们系统上安装的许多软件包都有位于 /usr/share/doc 目录中的文档文件。其中大部分以纯文本格式存储,可以用更少的资源查看。其中一些文件是HTML格式的,可以用网络浏览器查看。我们可能会遇到一些以 .gz 扩展名结尾的文件。这表示它们已被 gzip
压缩程序压缩。 gzip
包包括一个less
的特殊版本 zless
,它将显示 gzip
压缩文本文件的内容。
alias
创建我们自己的命令现在让我们第一次体验编程!我们将使用 alias
命令创建自己的命令。但在我们开始之前,我们需要揭示一个小的命令行技巧。通过用分号分隔每个命令,可以在一行上放置多个命令。其工作原理如下:
*command1; command2; command3 ...
以下是我们将使用的示例:
xxxxxxxxxx
[me@linuxbox ~]$ cd /usr; ls; cd -
bin games include lib local sbin share src
/home/me
[me@linuxbox ~]$
正如我们所看到的,我们在一行中组合了三个命令。首先,我们将目录更改为 /usr ,然后列出该目录,最后返回到原始目录(使用 cd-
),这样我们就回到了起点。现在,让我们使用 alias
将此序列转换为新命令。我们要做的第一件事就是为我们的新命令想出一个名字。让我们试试 test
。在我们这样做之前,最好先弄清楚 test
这个名字是否已经被使用了。为了找到答案,我们可以再次使用 type
命令:
xxxxxxxxxx
[me@linuxbox ~]$ type test
test is a shell builtin
哎呀!名称测试已进行。让我们试试 foo
:
xxxxxxxxxx
[me@linuxbox ~]$ type foo
bash: type: foo: not found
太棒了 foo
未被占用。那么,让我们创建我们的别名:
xxxxxxxxxx
[me@linuxbox ~]$ alias foo='cd /usr; ls; cd -'
请注意此处显示的此命令的结构:
alias name='string'
在命令 alias
之后,我们给 alias
一个名称,后面紧跟一个等号(不允许有空格),后面紧跟着一个引号字符串,其中包含要赋予该名称的含义。定义别名后,我们可以在shell需要命令的任何地方使用它。让我们试试:
xxxxxxxxxx
[me@linuxbox ~]$ foo
bin games include lib local sbin share src
/home/me
[me@linuxbox ~]$
我们还可以再次使用 type
命令来查看我们的别名:
xxxxxxxxxx
[me@linuxbox ~]$ type foo
foo is aliased to `cd /usr; ls; cd -'
要删除别名,可以使用 unalias
命令,如下所示:
xxxxxxxxxx
[me@linuxbox ~]$ unalias foo
[me@linuxbox ~]$ type foo
bash: type: foo: not found
虽然我们有意避免用现有的命令名命名别名,但这样做并不罕见。这通常是为了在每次调用公共命令时应用一个常用的选项。例如,我们之前看到 ls
命令经常被别名化以添加颜色支持:
xxxxxxxxxx
[me@linuxbox ~]$ type ls
ls is aliased to `ls --color=tty'
要查看环境中定义的所有别名,请使用不带参数的 alias
命令。以下是Fedora系统上默认定义的一些别名。试着弄清楚他们都在做什么:
xxxxxxxxxx
[me@linuxbox ~]$ alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
在命令行上定义别名有一个小问题。当我们的shell会话结束时,它们就会消失。在【第11章.环境】中,我们将看到如何在每次登录时将我们自己的别名添加到建立环境的文件中,但现在,我们已经迈出了shell编程世界的第一步,尽管很小!
现在我们已经学习了如何查找命令的文档,去查找到目前为止我们遇到的所有命令的文档。研究还有哪些其他选择,并尝试一下!