Unix 指南/解释/引用和文件名扩展
Shell 识别几个特殊字符。以下是特殊字符
- \ (反斜杠)
- " (双引号)
- ' (单引号)
- # {数字符号、磅符号或井号)
- $ (美元符号)
- ` (反引号)
- ~ (波浪号)
- { 和 } (大括号或花括号)
- ( 和 ) (圆括号)
- * (星号、星号或星号)
- ? (问号)
- < (小于号)
- > (大于号)
- & (和号)
- | (管道)
- ; (分号)
- ! (感叹号或感叹号)
除了感叹号外,它们都是 Bourne Shell 中的特殊字符。然而,许多 Bourne 和非 Bourne Shell 也将感叹号作为特殊字符。当 Shell 看到特殊字符时,它会执行比简单地运行你键入的命令更复杂的操作。
一些特殊字符会触发替换,命令的一部分会被替换成其他文本。一种常见的替换形式是文件名扩展,这在键入较长的文件名和文件名列表时可以节省工作。
要测试替换,我们需要echo命令。此命令只是回显其参数(包括 Shell 对参数进行的任何更改)。除了“-n”之外,所有选项都被忽略。
$ echo -lnQ arg1 arg2 arg3 -lnQ arg1 arg2 arg3
引用用于保留特殊字符的字面含义。
以下是一个关于几种类型引用的示例,这些示例将在本节的其余部分中引用(其中有很多不必要的东西,你应该在阅读完本节后找到它们,但它们用于示例)
$ echo There is \"a small possibility\" that '/etc/*tab' are " not " text and a backslash will not be printed after this. \\ There is "a small possibility" that /etc/*tab are not text and a backslash will not be printed after this. \
反斜杠(\)只是阻止 Shell 认为某些字符是特殊的。在上面的示例中,它用于按字面意义打印双引号字符。
要打印反斜杠,请连续使用两个反斜杠。
现在需要特殊 Shell 字符作为输入的命令将起作用。
成对字符会影响它们之间的任何内容。
单引号会阻止所有扩展,从而保留所有字符的字面含义。
在示例中,单引号用于阻止 * 扩展。
单引号不能用在单引号中。任何第二个单引号都会终止第一个单引号,而第三个单引号则开始下一对单引号。
双引号类似于单引号,但不会保留 $, \ (当后面跟着美元符号、反引号、双引号或反斜杠时)和 ` 的字面含义。
在示例中,双引号用于保留空格的字面含义。
文件名扩展使用以下字符来避免键入很长的文件列表
* ? { }
Shell通配符 * 和 ? 用于构成模式。Shell 会搜索与模式匹配的现有文件并进行替换。
- *匹配 0 个或多个字符,除了 /
- ?匹配除 / 之外的任何一个字符
当匹配到多个文件时,这些文件用空格隔开,作为单独的参数。
例如,/etc/ss*表示所有在/etc目录中以字母ss开头的文件。echo 命令演示了替换。结果可能因你的系统而异,具体取决于你拥有的文件。
$ echo /etc/ss* /etc/ssh /etc/ssl
echo 命令之所以这样做,是因为它认为你运行了echo /etc/ssh /etc/ssl。Shell 用这些名称替换了/etc/ss*。虽然/etc/ssh/ssh_config在许多系统上都存在,但它没有出现在上面,因为*永远不会匹配/.
现在这里有一些更有用的东西。我们将使用除“echo”之外的命令进行替换。我们将文件名扩展与 ls 命令结合起来。
$ ls /etc/ss* /etc/ssh: ssh_config ssh_host_key ssh_host_rsa_key.pub ssh_host_dsa_key ssh_host_key.pub sshd_config ssh_host_dsa_key.pub ssh_host_rsa_key /etc/ssl: lib openssl.cnf private x509v3.cnf
注意 * 如何减少额外的键入。如果我们执行ls /etc/s*,我们可能会进一步减少用户需要键入的量。
以下是一个 ? 字符起作用的示例
$ ls /etc/ssh/ssh_host_???_key /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_rsa_key
有时,使用 * 或 ? 时,找不到任何文件。在这种情况下,Shell 不会报错;它只是不进行替换。假设在上面的示例中的机器上,我们犯了个错误,键入了/etc/sss*,它不匹配任何内容。那么 Shell 不会进行任何替换
$ echo /etc/sss* /etc/sss*
当键入多个类似的参数(特别是文件名)时,花括号很有帮助。文件名实际上并不需要存在。示例
$ echo /etc/ss{h,l,ssnakes} /etc/ssh /etc/ssl /etc/ssssnakes
它们对于同一目录中很长的文件列表非常有用
$ echo /bin/{ls,mv,cp} /sbin/{halt,reboot} /bin/ls /bin/mv /bin/cp /sbin/halt /sbin/reboot
你也可以用它们来打印字母表(或数字)
$ 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