Shell|GNU Bash 参考手册:3.6 重定向|V20240921

声明:本文梳理自 GNU Bash 参考手册:https://www.gnu.org/software/bash/manual/bash.html;部分借鉴自通义千问 AI。

3.6 重定向(Redirections)

在执行命令之前,可以使用 shell 解释的特殊符号将其输入和输出进行重定向(redirection)。重定向允许命令的文件描述符被复制、打开、关闭,或者指向不同的文件,并且能够改变命令读取和写入的文件。重定向也可以用来修改当前 shell 执行环境中的文件描述符。下面列出的重定向操作符可以在简单命令之前、之中或之后出现。重定向按照从左到右的顺序处理。

每个可以由文件描述符号码前导的重定向,也可以由形如 {varname} 的词前导。在这种情况下,除了 >&-<&- 之外的每个重定向操作符,shell 都会分配一个大于 10 的文件描述符并将其赋值给 {varname}。如果 >&-<&-{varname} 前导,则 varname 的值定义了要关闭的文件描述符。如果提供了 {varname},则重定向将持续超过命令的作用域,允许 shell 程序员手动管理文件描述符的生命周期。varredir_close shell 选项管理此行为(详见 “4.3.2 内置 Shopt 命令”)。

在以下描述中,如果省略了文件描述符号码:

  • 如果重定向操作符的第一个字符是 <,则该重定向指的是标准输入(文件描述符 0
  • 如果重定向操作符的第一个字符是 >,则该重定向指的是标准输出(文件描述符 1

在以下描述中,重定向操作符后面跟随的词,除非另有说明,将经历括号展开、波浪线展开、参数展开、命令替换、算术展开、引号移除、文件名展开以及单词分割。如果它展开了多于一个词,Bash 将报告错误。

需要注意的是,重定向的顺序是很重要的。例如:

ls > dirlist 2>&1

将标准输出(文件描述符 1)和标准错误(文件描述符 2)都导向文件 dirlist,而命令

ls 2>&1 > dirlist

只将标准输出导向文件 dirlist,因为标准错误在标准输出被重定向到 dirlist 之前已经被设置为标准输出的一个副本。

Bash 在重定向中使用几个特殊文件名时会进行特殊处理,如下表所述。如果运行 Bash 的操作系统提供了这些特殊文件,Bash 将使用它们;否则,它将在内部模拟这些文件,并表现出以下描述的行为。

  • /dev/fd/fd:如果 fd 是一个有效的整数,则复制文件描述符 fd。
  • /dev/stdin:复制文件描述符 0。
  • /dev/stdout:复制文件描述符 1。
  • /dev/stderr:复制文件描述符 2。
  • /dev/tcp/host/port:如果 host 是一个有效的主机名或互联网地址,并且 port 是一个整数端口号或服务名称,Bash 会尝试打开相应的 TCP socket
  • /dev/udp/host/port:如果 host 是一个有效的主机名或互联网地址,并且 port 是一个整数端口号或服务名称,Bash 会尝试打开相应的 UDP socket。

打开或创建文件失败会导致重定向失败。

使用大于 9 的文件描述符进行重定向时应谨慎,因为它们可能会与 shell 内部使用的文件描述符产生冲突。

3.6.1 重定向输入(Redirected Input)

输入(input)重定向会导致由单词扩展得到的文件名所对应的文件以读取模式打开,并且该文件被关联到文件描述符 n 上;如果没有指定 n,则默认使用标准输入(文件描述符 0)。

输入重定向的一般格式为:

[n]<word

其中的 [n] 是可选的文件描述符编号,如果省略,则默认为 0(即标准输入);word 代表要打开的文件名,它可能会经过 shell 的扩展处理。例如,将 data.txt 文件作为命令的标准输入:

command < data.txt
3.6.2 重定向输出(Redirected Output)

输出(output)重定向会导致由 word 展得到的文件名所对应的文件以写入模式打开,并且该文件被关联到文件描述符 n 上;如果没有指定 n,则默认使用标准输出(文件描述符 1)。如果文件不存在,则会创建该文件;如果文件已经存在,则它会被截断至零大小(即清空文件内容)。

输出重定向的一般格式为:

[n]>[|]word
  • 如果重定向操作符是 >,并且内置命令 setnoclobber 选项已被启用,那么当由 word 扩展得到的文件名对应的文件存在且是一个普通文件时,重定向将会失败。
  • 如果重定向操作符是 >|,或者重定向操作符是 >noclobber 选项未被启用,即使由 word 指定的文件已存在,重定向也会尝试执行。
3.6.3 追加重定向输出(Appending Redirected Output)

重定向输出以这种方式会导致由单词扩展得到的文件名被打开用于在文件描述符 n 上追加内容,如果未指定 n,则默认为标准输出(文件描述符 1)。如果文件不存在,则会创建该文件。

追加输出的一般格式是:

[n]>>word
3.6.4 重定向标准输出和标准错误输出(Redirecting Standard Output and Standard Error)

这种结构允许将标准输出(文件描述符1)和标准错误输出(文件描述符2)都重定向到由单词扩展得到的文件名所指定的文件中。

对于重定向标准输出和标准错误,有两种格式:

&>word

>&word

在这两种形式中,推荐使用第一种。这在语义上等同于

>word 2>&1

当使用第二种形式时,word 不能扩展为一个数字或 -。如果它确实扩展成了这些值,那么为了兼容性原因,会应用其他重定向操作符。(详见下文 “Duplicating File Descriptors”)

3.6.5 追加重定向标准输出和标准错误输出(Appending Standard Output and Standard Error)

这种结构允许将标准输出(文件描述符1)和标准错误输出(文件描述符2)都追加到由单词扩展得到的文件名所指定的文件中。

追加标准输出和标准错误的格式是:

&>>word

这在语义上等同于

>>word 2>&1

(详见下文 “Duplicating File Descriptors”)

3.6.6 Here Documents

这种类型的重定向告诉 shell 从当前源读取输入,直到遇到一行只包含 word(没有尾随空格)为止。到那时为止读取的所有行都将用作命令的标准输入(如果指定了 n,则作为文件描述符 n)。

Here Document 的格式是:

[n]<<[-]word
        here-document
delimiter

word 上不会执行任何参数和变量扩展、命令替换、算术扩展或文件名扩展。如果 word 的任何部分被引号包围,那么 delimiter 就是对 word 进行引号移除后的结果,并且 here document 中的行不会被扩展。如果 word 没有被引号包围,here document 中的所有行都会经过参数扩展、命令替换和算术扩展处理,字符 \n 会被忽略,并且必须使用 \ 来转义字符 \$ 和 `。

如果重定向操作符是 <<-,那么会从输入行和包含 delimiter 的行中删除所有的前导制表符。这允许 shell 脚本中的 here document 以自然的方式缩进。

3.6.7 Here Strings

这是一种 here document 的变体,其格式为:

[n]<<< word

这里的 word 会经历波浪线展开、参数和变量展开、命令替换、算术展开以及引号移除。但不会进行文件名扩展和单词拆分。最终的结果作为一个单独的字符串,并在末尾追加一个换行符,提供给命令的标准输入(如果指定了 n,则是文件描述符 n)。

3.6.8 复制文件描述符

重定向操作符:

[n]<&word

用于复制输入文件描述符。如果 word 展开为一个或多个数字,那么由 n 表示的文件描述符将被设置为该文件描述符的一个副本。如果 word 中的数字没有指定一个打开的输入文件描述符,则会发生重定向错误。如果 word 的值为 -,则关闭文件描述符 n。如果没有指定 n,则使用标准输入(文件描述符0)。

类似的,重定向操作符:

[n]>&word

用于复制输出文件描述符。如果没有指定 n,则使用标准输出(文件描述符1)。如果 word 中的数字没有指定一个打开的输出文件描述符,则会发生重定向错误。如果 word 的值为 -,则关闭文件描述符 n。作为特殊情况,如果省略了 n 并且 word 不展开为一个或多个数字或 -,则标准输出和标准错误将按前面所述的方式被重定向。

3.6.9 移动文件描述符

重定向操作符:

[n]<&digit-

将文件描述符 digit 移动到文件描述符 n,如果未指定 n,则移动到标准输入(文件描述符 0)。在被复制到 n 后,digit 将被关闭。

类似地,重定向操作符:

[n]>&digit-

将文件描述符 digit 移动到文件描述符 n,如果未指定 n,则移动到标准输出(文件描述符 1)。在被复制到 n 后,digit 也将被关闭。

3.6.10 打开文件描述符以进行读写

重定向操作符:

[n]<>word

会导致名称为 word 展开后所指的文件在文件描述符 n 上被打开,以便同时进行读取和写入操作;如果没有指定 n,则会在文件描述符 0 上进行。如果该文件不存在,则会被创建。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值