重定向(REDIRECTION) ================= 在命令执行前,它的输入和输出可能被重定向(`redirect`),使用一种`shell`可以解释的特殊记法。 重定向也可以用于为当前`shell`执行环境打开和关闭文件。 下列重定向操作符可以前置或者放在简单命令(`simple command`)之中的任何位置,或者放在命令之后。 重定向是以出现的顺序进行处理的,从左到右。 下列描述中,如果文件描述符被忽略,并且第一个重定向操作符是`<`,那么重定向指的是标准输入(文件描述符是`0`)。 如果重定向操作符的第一个字符是`>`,那么重定向指的是标准输出(文件描述符是`1`)。 下列描述中,重定向操作符之后的词如果没有特殊说明,都要经过brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, pathname expansion, 还有 word splitting。 如果扩展为多于一个词,`bash`将报错。 注意重定向的顺序非常重要。例如,命令 ```bash ls > dirlist 2>&1 ``` 将标准输出和标准错误重定向到文件`dirlist`,而命令 ```bash ls 2>&1 > dirlist ``` 只会将标准输出重定向到文件`dirlist`,因为在标准输出被重定向到文件`dirlist`中之前,标准错误被复制为标准输出。 一些文件名在重定向中被`bash`特殊处理,如下表所示: - `/dev/fd/` 如果``是一个合法的整数,文件描述符``将被复制。 - `/dev/stdin` 文件描述符`0`被复制。 - `/dev/stdout` 文件描述符`1`被复制。 - `/dev/stderr` 文件描述符`2`被复制。 - `/dev/tcp//` 如果``是一个合法的主机名或`Internet`地址,并且``是一个整数端口号或服务名,`bash`试图建立与相应的套接字的`TCP`连接。 - `/dev/udp//` 如果``是一个合法的主机名或`Internet`地址,并且``是一个整数端口号或服务名,`bash`试图建立与相应的套接字的`UDP`连接。 打开或创建文件错误将导致重定向出错。 重定向输入 ----------------- 重定向输入(`Redirecting Input`)使得以`word`扩展结果为名的文件被打开并通过文件描述符`n`读取,如果没有指定`n`那么就作为标准输入(文件描述符为`0`)读取。 重定向输入的一般形式是: ```bash [n]word ``` 如果重定向操作符是`>`,并且启用了内建命令`set`的`noclobber`选项,那么如果`word`扩展后得到的文件名存在并且是一个普通的文件,重定向将失败。 如果重定向操作符是`>|`, 或者重定向操作符是`>`并且没有启用内建命令`set`的`noclobber`选项,那么即使`word`得出的文件名存在,也会尝试进行重定向。 追加式重定向输出(`Appending Redirected Output`) --------------- 这种方式的输出重定向使得以`word`扩展结果为名的文件被打开并通过文件描述符`n`从尾部添加。 如果没有指定`n`就使用标准输出(文件描述符`1`)。如果文件不存在,它将被创建。 重定向的一般形式是: ```bash [n]>>word ``` Redirecting Standard Output and Standard Error `bash`允许使用这种结构将标准输出和标准错误(文件描述符`1`和`2`) 重定向到以`word`扩展结果为名的文件中。 有两种重定向标准输出/标准错误的形式: ```bash &>word ``` 还有 ```bash >&word ``` 两种形式中,推荐使用第一种。它与 ```bash >word 2>&1 ``` 在语义上等价。 Here Documents --------------- 这种重定向使得`shell`从当前源文件读取输入,直到遇到仅包含`word`的一行(并且没有尾部空白)为止。 直到这一点的所有行被用作 命令的标准输入。 `here-document`的格式是: ```bash <<[-]word here-document delimiter ``` 不会对`word`进行参数扩展、命令替换、算术扩展或者路径名扩展。 如果`word`中任何字符是引用的,`delimiter`将是对`word`进行引用删除的结果,`here-document`中的行不会被扩展。 如果`word`没有被引用,`here-documnet`中的所有行都要经过参数扩展、命令替换和算术扩展。 在后一种情况下,字符序列`\`被忽略;必须用`\`来引用字符`\`、`$`和 `\``。 如果重定向操作符是`<<-`, 那么所有前导的`tab`字符都被从输入行和包含`delimiter`的行中删除。 这样使得`shell`脚本中的`here-document`可以被更好地缩进。 Here Strings --------------- `here-document`的变种,形式是 ```bash <<&word ``` 用于复制输出文件描述符。 如果没有指定`n`,将使用标准输出(文件描述符`1`)。 如果`word`中的数字并未指定一个被用于输出的文件描述符,将产生一个重定向错误。 特殊情况下,如果忽略了`n`,并且`word`并非扩展为一个或多个数字,标准输出和标准错误将被重定向,和前面描述的一样。 Moving File Descriptors --------------------- 重定向操作符 [n]<&digit- 将文件描述符`digit`移动为文件描述符`n`;如果没有指定`n`,则移动标准输入(文件描述符`0`) `digit`复制为`n`之后就被关闭了。 类似的,重定向操作符 ```bash [n]>&digit- ``` 将文件描述符`digit`移动为文件描述符`n`,或标准输出(文件描述符`1`),如果没有指定`n`的话。 Opening File Descriptors for Reading and Writing ---------------------- 重定向操作符 ```bash [n]<>word ``` 使得以`word`扩展结果为名的文件被打开,通过文件描述符`n`进行读写。 如果没有指定`n`那么就使用文件描述符`0`。如果文件不存在,它将被创建。