「Bash」- 重定向| REDIRECTION

在执行命令之前,可以使用 Shell 解释的特殊表示法重定向其输入和输出。重定向允许命令的文件句柄被复制、打开、关闭、用于引用不同的文件,并且可以更改命令读取和写入的文件。重定向还可用于修改当前 Shell 执行环境中的文件句柄。以下重定向运算符可以前缀或出现在简单命令的任何位置,也可以跟随命令。重定向按其出现的顺序从左到右处理。

每个重定向可以被前缀一个文件描述符号,或者被前缀一个{varname}形式的单词。在这种情况下,除>&-<&-之外,每个重定向运算符,Shell 将分配大于或等于 10 的文件描述符,并将其分配给 varname。如果>&-<&-前面有{varname},则varname的值定义要关闭的文件描述符。

在以下描述中,如果省略文件描述符号,并且重定向运算符的第一个字符是<,则重定向指的是标准输入(文件描述符 0)。如果重定向运算符的第一个字符是>,则重定向引用标准输出(文件描述符 1)。

除非另有说明,否则以下描述中的重定向运算符后面的单词将受到括号展开、波浪线展开、参数和变量展开、命令替换、算术展开、引用删除、路径名展开、单词拆分的影响。如果它展开为多个单词,Bash 会报告错误。

请注意,重定向的顺序很重要。例如,命令ls > dirlist 2>&1,将标准输出和标准错误都指向 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 套接字。

/dev/udp/host/port,如果 host 是有效的主机名或网络地址,并且 port 是整数端口号或服务名称,则 bash 会尝试打开相应的 UDP 套接字。

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

应谨慎使用使用大于 9 的文件描述符的重定向,因为它们可能与 Shell 在内部使用的文件描述符冲突。

请注意,内建的 exec 命令可以使重定向在当前 Shell 中生效。

输入重定向(Redirecting Input)

输入重定向的一般格式是:[n]<word

输入重定向导致打开名称由word展开后产生的文件,以便在文件描述符n上读取。或者如果未指定 n,则打开标准输入(文件描述符0)。

输出重定向(Redirecting Output)

输出重定向的一般格式是:[n]>word

输出重定向导致打开名称由word展开产生的文件,以便在文件描述符n上写入。或者如果未指定n,则打开标准输出(文件描述符1)。如果文件不存在则创建;如果确实存在,则将其截断为零大小。

如果重定向运算符是>,并且已启用内建命令setnoclobber选项,则如果名称由单词展开产生的文件存在且是常规文件,则重定向将失败。如果重定向运算符是>|,或者重定向运算符是>且未启用内建命令setnoclobber选项,则即使存在由word命名的文件,也会尝试重定向。

追加输出重定向(Appending Redirected Output)

追加输出重定向的一般格式是:[n]>>word

以这种方式重定向输出会导致名称由word展开产生的文件打开,然后追加到文件描述符n上,而不是截断已经存在的文件。或者如果未指定n则打开标准输出(文件描述符 1)。如果该文件不存在,则创建该文件。

重定向标准输出和标准错误(Redirecting Standard Output and Standard Error)

重定向标准输出和标准错误有两种格式:&>word>&word。在这两种形式中,第一种是优选的。在语义上等同于>word 2>&1的形式。

此构造允许将标准输出(文件描述符 1)和标准错误(文件描述符 2)重定向到名为 word 展开的文件。

使用第二种形式时,word可能不会展开为数字或-。如果是,则应用其他重定向运算符(请参阅下面的“复制文件描述符”)以了解兼容性原因。

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

追加标准输出和标准错误的格式为:&>>word。语义上等同于>>word 2>&1

此构造允许将标准输出(文件描述符 1)和标准错误输出(文件描述符 2)附加到名称为 word 展开的文件。

(请参阅下面的“复制文件描述符”)

Here Doc 的格式是:

这种类型的重定向指示 Shell 从当前源读取输入,直到看到“只包含 delimiter 的行”(没有尾随空白)。然后,读取到该点的所有行都用作命令的标准输入(或者如果指定了 n,则为文件描述符 n)。

不对word执行参数和变量展开、命令替换、算术展开、路径名展开。如果对word任何部分加了引号,则delimiter是单词上的引号删除的结果,并且不会展开 here-document 中的行。如果word不加引号,则 here-document 的所有行都要进行参数展开、命令替换、算术展开,忽略字符序列\<newline>,并且必须使用\来引用字符\$`

如果重定向运算符是<<-,则从输入行和包含 delimiter 的行中删除所有前导制表符(TAB)。这允许 Shell 脚本中的 here-documents 以自然的方式缩进。

一种 Here Doc 的变体,格式为:[n]<<<word

word经历括号展开,波浪线展开,参数和变量展开,命令替换,算术展开,引用删除。不执行路径名展开、单词拆分。结果作为单个字符串提供,并在其标准输入上添加换行符(如果指定了 n,则为文件描述符 n)。

复制文件描述符(Duplicating File Descriptors)

重定向运算符[n]<&word用于复制输入文件描述符。如果word扩展为一个或多个数字,则由n表示的文件描述符将成为该文件描述符的副本。如果word中的数字未指定打开输入的文件描述符,则会发生重定向错误。如果 word 求值为-,则关闭文件描述符 n。如果未指定 n,则使用标准输入(文件描述符 0)。

重定向运算符[n]>&word的使用是类似的,复制输出文件描述符。如果未指定n,则使用标准输出(文件描述符 1)。如果word中的数字未指定打开输出的文件描述符,则会发生重定向错误。如果 word 求值为-,则关闭文件描述符 n。作为一种特殊情况,如果省略 n,并且 word 不会扩展为一个或多个数字或-,则标准输出和标准错误将重定向,如前所述。

移动文件描述符(Moving File Descriptors)

重定向运算符[n]<&digit-,则将文件描述符digit移动到文件描述符n。如果未指定n,默认标准输入(文件描述符 0)。digit在复制到n后关闭。

重定向运算符[n]>&digit-,则将文件描述符digit移动到文件描述符n。如果未指定n,默认标准输出(文件描述符 0)。digit在复制到n后关闭。

打开文件描述符进行读写(Opening File Descriptors for Reading and Writing)

重定向运算符[n]<>word,导致名称为 word 扩展的文件打开,在文件描述符 n 上读取和写入时,如果未指定 n 则在标准输入(文件描述符 0)上打开。如果该文件不存在,则创建该文件。

-r,忽略所有已经记忆的命令位置。

-d,忽略 name 对应的命令位置。

-a,创建或修改的每个变量和函数,都会被给予 export 属性并标记,以导出(export)到后续命令的环境。

简而言之,我们能够在子命令(或子脚本)中调用当前脚本中定义的变量,而无需单独使用 export 关键字。如下示例:

./sub-script # 在该脚本中,我们能够使用 FOO 变量,因为它已经被自动 export 为环境变量