"3>&1 1>&2 2>&3" 在脚本中有什么作用?

jst*_*err 84 shell bash io-redirection file-descriptors

我在脚本中看到了这一行:

DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das 
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`
Run Code Online (Sandbox Code Playgroud)

什么是

3>&1 1>&2 2>&3
Run Code Online (Sandbox Code Playgroud)

正在做?我知道 1 = stdout 和 2 = stderr,但是 the3和 the &for 是什么?

Ulr*_*gel 96

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

0 - stdin
1 - stdout
2 - stderr
Run Code Online (Sandbox Code Playgroud)

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

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,反之亦然。

  • 我的问题是 - shell 脚本如何知道要传递给“3”的内容?假设你运行了一个 `echo "hello" | 3>&1` - 它会通过管道将“hello”传递到 `3` 文件描述符,然后传递到 STDOUT 吗? (2认同)

Mik*_*kel 26

它正在交换stdoutstderr

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

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

所以&需要告诉shell你的意思是文件描述符,而不是文件名。

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

默认情况下,文件描述符12go to /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
Run Code Online (Sandbox Code Playgroud)

所以也许编写脚本的人希望dialog's 的输出stdout而不是stderr出于某种原因。

另请参阅重定向顺序


Jon*_*son 5

脚本编写者定义了 fd 3,例如:

exec 3<> File.txt
Run Code Online (Sandbox Code Playgroud)

打开“File.txt”并将 fd 3 分配给它。最大文件描述符:255

read -n 4 <&3
Run Code Online (Sandbox Code Playgroud)

只读 4 个字符。

echo -n . >&3
Run Code Online (Sandbox Code Playgroud)

在那里写一个小数点。

exec 3>&-
Run Code Online (Sandbox Code Playgroud)

关闭 fd 3。

cat File.txt
Run Code Online (Sandbox Code Playgroud)

==> 1234.67890

  • https://www.tldp.org/LDP/abs/html/io-redirection.html (2认同)