![“3>&1 1>&2 2>&3”在脚本中起什么作用?](https://linux22.com/image/23840/%E2%80%9C3%3E%261%201%3E%262%202%3E%263%E2%80%9D%E5%9C%A8%E8%84%9A%E6%9C%AC%E4%B8%AD%E8%B5%B7%E4%BB%80%E4%B9%88%E4%BD%9C%E7%94%A8%EF%BC%9F.png)
我在脚本中看到了这一行:
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
命令行中的 将会创建一个新的文件描述符并将其重定向1
到STDOUT
.现在1>&2
将文件描述符 1 重定向到STDERR
并将2>&3
文件描述符 2 重定向到 3,即STDOUT
.
所以基本上你切换了STDOUT
和STDERR
,这些是步骤:
- 创建一个新的fd 3并将其指向fd 1
- 将文件描述符 1 重定向到文件描述符 2。如果我们不将文件描述符保存在 3 中,我们就会丢失目标。
- 将文件描述符 2 重定向到文件描述符 3。现在文件描述符 1 和文件描述符 2 已交换。
现在,如果程序将某些内容打印到文件描述符 1,它将被打印到文件描述符 2,反之亦然。
答案2
它正在交换stdout
和stderr
。
>name
表示将输出重定向到文件name
。
>&number
意味着将输出重定向到文件描述符number
。
因此&
需要告诉 shell 您指的是文件描述符,而不是文件名。
文件描述符是指一个已经打开的文件的数字。标准0
用于标准输入、1
标准输出或2
标准错误。您还可以使用任何其他数字,这将创建一个新的文件描述符,就像您使用 . 创建一个新变量一样var=value
。
默认情况下,文件描述符1
和2
go 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"
当您运行此示例时,您将看到文件描述符被重新排列并且输出发生变化。