“3>&1 1>&2 2>&3”在脚本中起什么作用?

“3>&1 1>&2 2>&3”在脚本中起什么作用?

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

DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das 
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`

什么是

3>&1 1>&2 2>&3

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

答案1

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

0 - stdin
1 - stdout
2 - stderr

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

3>&1命令行中的 将会创建一个新的文件描述符并将其重定向1STDOUT.现在1>&2将文件描述符 1 重定向到STDERR并将2>&3文件描述符 2 重定向到 3,即STDOUT.

所以基本上你切换了STDOUTSTDERR,这些是步骤:

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

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

答案2

它正在交换stdoutstderr

>name表示将输出重定向到文件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

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

也可以看看重定向顺序

答案3

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

exec 3<> File.txt

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

read -n 4 <&3

只读 4 个字符。

echo -n . >&3

在那里写一个小数点。

exec 3>&-

关闭 fd 3。

cat File.txt

==> 1234.67890

答案4

我通过下面的示例理解了文件描述符和“3> & 1 1> & 2 2> & 3”命令的用途

#!/bin/bash
#it's normal case fd environment

echo test 1> afile.txt
echo "Test no 1"
cat afile.txt
echo "Test no 1"

echo test 2> afile.txt
echo "Test no 2"
cat afile.txt
echo "Test no 2"

echo test 1> afile.txt
echo "Test no 3"
cat afile.txt
echo "Test no 3"
echo test 2> afile.txt

echo "Test no 4"
cat afile.txt
echo "Test no 4"
echo > afile.txt

echo "------------------------------------------------------------------------"

#it's relocate filedescriptor and cause not problem, and cause error(std error)

var=
var=$(echo test 3>&1 1>&2 2>&3)

echo "Test no 5"
#cat afile.txt
echo $var
echo "Test no 5"

var=
var=$(echo test 3>&1 1>&2 2>&3)

echo "Test no 6"
#cat afile.txt
echo $var
echo "Test no 6"

var=
var=$(echo test 3>&1 1>&2 2>&3)

echo "Test no 7"
#cat afile.txt
echo $var
echo "Test no 7"

var=
var=$(echo test 3>&1 1>&2 2>&3)

echo "Test no 8"
#cat afile.txt
echo $var
echo "Test no 8"

当您运行此示例时,您将看到文件描述符被重新排列并且输出发生变化。

相关内容