3.6 重定向
在执行命令之前,它的输入和输出可能会使用由 shell 解释的特殊符号来重定向。 重定向允许命令文件句柄被复制、打开、关闭,使其指向不同的文件,并且可以更改命令读取和写入的文件。 重定向也可以被用来修改当前shell执行环境中的文件句柄。下面的重定向操作符可以出现在简单命令的前面或任何地方,也可以跟在命令后面。 重定向按照它们出现的顺序处理,从左到右。
每个可能以文件描述符编号开头的重定向都可以以 {varname} 形式的单词开头。在这种情况下,除了>&-和<&-之外,对于每个重定向操作符,shell将分配一个大于10的文件描述符并将其分配给{varname}。如果>&-或<&-前面有{varname},varname的值就定义了要关闭的文件描述符。 如果提供了{varname},重定向就会持续到命令的范围之外,允许shell程序员手动管理文件描述符的寿命。 varredir_close
shell选项管理这种行为(参见The Shopt Builtin)。
在下面的描述中,如果省略了文件描述符的编号,并且重定向操作符的第一个字符是‘<’,重定向指的是标准输入(文件描述符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套接字。
/dev/udp/host/port
如果host是一个有效的主机名或互联网地址,并且port是一个整数的端口号或服务名称,Bash就会尝试打开相应的UDP套接字。
打开或创建文件的失败会导致重定向的失败。
使用大于9的文件描述符的重定向应该小心使用,因为它们可能会与shell内部使用的文件描述符相冲突。
1 重定向输入
输入的重定向使word扩展后的文件名在文件描述符n
上被打开以便阅读,如果没有指定n
,则在标准输入(文件描述符0)上被打开。
重定向输入的一般格式是:
[n]<word
2 重定向输出
输出重定向导致其名称由word产生的文件被打开用于在文件描述符n上写入,如果没有指定n,则在标准输出(文件描述符1)。如果该文件不存在,它将被创建;如果它存在,它将被截断为零大小。
重定向输出的一般格式是:。
[n]>[|]word
如果重定向操作符是‘>’,并且已经启用了set
内置的noclobber
选项,那么如果由word扩展出来的文件名存在并且是一个常规文件,重定向将会失败。如果重定向操作符是‘>|’,或者重定向操作符是‘>’,并且noclobber
选项未被启用,即使word命名的文件存在,也会尝试重定向。
3 追加重定向输出
以这种方式重定向输出会导致文件名由word扩展而来的文件被打开以追加到文件描述符n上,如果没有指定n的话,则是标准输出(文件描述符1)。如果该文件不存在,它将被创建。
追加输出的一般格式是:
[n]>>word
4 重定向标准输出和标准错误
这个结构允许标准输出(文件描述符1)和标准错误输出(文件描述符2)都被重定向到名字是word扩展的文件中。
有两种格式可用于重定向标准输出和标准错误。
&>word
和
>&word
在这两种形式中,第一种形式更受欢迎。 这在语义上等同于
>word 2>&1
当使用第二种形式时,word可能不会扩展为数字或‘-’。如果是这样,由于兼容性的原因,其他重定向操作符也适用(见下面的复制文件描述符)。
5 追加标准输出和标准错误
这个结构允许将标准输出(文件描述符1)和标准错误输出(文件描述符2)都追加到名称是word扩展的文件中。
追加标准输出和标准错误的格式是:
&>>word
这在语义上等效于
>>word 2>&1
(见下面的复制文件描述符)。
6 这里的文件
这种类型的重定向指示shell从当前源读取输入,直到看到一个只包含字的行(没有尾部空白)。然后,所有读到这一点的行都被用作一个命令的标准输入(或文件描述符n,如果指定了n)。
这里的文件格式是:
[n]<<[-]word
here-document
delimiter
没有对word进行参数和变量扩展、命令替换、算术扩展或文件名扩展。如果word的任何部分有引号,delimiter是对word去除引号的结果,here-document中的行不会被扩展。如果word不加引号,here-document的所有行都要进行参数扩展、命令替换和算术扩展,字符序列\newline
被忽略,而且必须用‘’来引用字符‘’、‘$’和‘`’。
如果重定向操作符是‘<<-’,那么所有前导的制表符都会从输入行和包含delimiter的行中剥离出来。 这使得 shell 脚本中的 her-documents 可以以自然的方式进行缩进。
7 这里的字符串
这里的文件的一个变体,格式是:
[n]<<< word
word经历了波浪号扩展、参数和变量扩展、命令替换、算术扩展和引号删除。 不执行文件名扩展和单词分割。 结果以单个字符串的形式提供给命令的标准输入(或文件描述符n,如果n被指定),并附加一个新行。
8 复制文件描述符
重定向运算符
[n]<&word
如果word扩展为一个或多个数字,那么n所表示的文件描述符就会成为该文件描述符的一个副本。如果word中的数字没有指定一个开放输入的文件描述符,就会发生重定向错误。 如果word评估为‘-’,文件描述符n被关闭。 如果没有指定n,就会使用标准输入(文件描述符0)。
命令
[n]>&word
是类似于重复输出文件描述符的用法。如果没有指定n,则使用标准输出(文件描述符1)。 如果word中的数字没有指定为输出打开的文件描述符,则发生重定向错误。 如果word评估为‘-’,文件描述符n被关闭。作为一种特殊情况,如果n被省略,并且word没有扩展到一个或多个数字或‘-’,标准输出和标准错误将被重定向,如前所述。
9 移动文件描述符
重定向操作
[n]<&digit-
将文件描述符digit移动到文件描述符n,如果没有指定n,则移动到标准输入(文件描述符0)。digit在被复制到n后被关闭。
同样地,重定向操作
[n]>&digit-
将文件描述符digit移动到文件描述符n,如果没有指定n,则移动到标准输出(文件描述符1)。
10 打开文件描述符进行读写
重定向操作者
[n]<>word
导致在文件描述符n上打开名称为word扩展的文件进行读写,如果没有指定n则在文件描述符0上打开。如果该文件不存在,它就会被创建。