脚本中的“ 3>&1 1>&2 2>&3”是做什么的?


Answers:


77

这些数字是文件描述符,只有前三个(从零开始)具有标准化的含义:

0 - stdin
1 - stdout
2 - stderr

因此,命令中的每个数字都引用文件描述符。您可以使用将文件描述符重定向到文件,也可以使用将文件描述符>重定向到另一个文件描述符。>&

3>&1你的命令行会创建一个新的文件描述符,并重定向它1STDOUT。现在1>&2将文件描述符1 重定向到STDERR2>&3并将文件描述符2重定向到3,即STDOUT

因此,基本上,您切换了STDOUTSTDERR,这些步骤是:

  1. 创建一个新的fd 3并将其指向fd 1
  2. 将文件描述符1重定向到文件描述符2。如果我们不将文件描述符保存到3中,我们将失去目标。
  3. 将文件描述符2重定向到文件描述符3。现在切换文件描述符1和2。

现在,如果程序将某些内容打印到文件描述符1,它将被打印到文件描述符2,反之亦然。


您已经说过:“命令行中的3>&1将创建一个新的文件描述符,并将其重定向到STDOUT 1”。但是1代表STDIN吗?
sofs1

19

正在交换stdoutstderr

>name表示将输出重定向到file name

>&number表示将输出重定向到文件描述符number

因此&需要告诉外壳程序您的意思是文件描述符,而不是文件名。

文件描述符是引用已经打开的文件的数字。标准的0用于标准输入,1用于标准输出或2用于标准误差。您还可以使用其他任何数字,这将创建一个新的文件描述符,就像使用来创建一个新变量一样var=value

默认情况下,文件描述符1和都2转到/dev/tty,因此,如果您somecommand 3>&1 1>&2 2>&3在新的Shell中运行,它不会更改任何内容(除非现在您的文件描述符编号为3)。

但是,如果脚本中较早的某个地方使用exec(例如exec 2>error.log)执行重定向,或者脚本使用包含重定向的命令行(例如./thescript 2>error.log)运行,那么交换stdout和stderr将会执行某些操作。

在您的特定情况下,交换其stdout和stderr的命令为dialog。看它的手册页,我看到了

Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error

因此也许编写脚本的人希望将dialog输出转到stdout而不是stderr出于某种原因。

另请参见重定向顺序


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.