这里2>&1是什么意思?

Gav*_*och -4 unix bash shell redirect

我在 bash 中尝试了这段代码:

 >$(
 >echo bonjour
 >echo bonsoir 2>&1
 >)
Run Code Online (Sandbox Code Playgroud)

所以就在那之后,结果是: bonsoir,当我这样做之后

>$ cat toto
Run Code Online (Sandbox Code Playgroud)

结果是:bonjour,我只是想了解 2>$1 在这里到底做了什么?

Geo*_*iou 7

在谈论重定向之前,我觉得你需要了解一个基本的事情:
Linux命令产生正常输出和错误输出,而unix让你可以自由地将每个输出“重定向”到一个单独的“通道”,称为文件描述符(fd) )。

Channel/fd 1 用于标准输出,Channel/fd 2 用于错误输出。

例如,您可以像这样运行命令:

$ command 1>output 2>errors #or more simple command >output 2>errors . A simple >output is a shortcut to 1>output
Run Code Online (Sandbox Code Playgroud)

在上面的命令中,屏幕上不会打印任何内容。正常输出将发送到名为“output”的本地文件,错误将发送到名为“errors”的本地文件。

现在想象一下您有两个监视器,分别名为 tty0 和 tty1。您可以使用类似的东西来区分输出

$ command 1>/dev/tty0 2>/dev/tty1
Run Code Online (Sandbox Code Playgroud)

在这种情况下,命令的正常输出将转到通道 1 = tty0,错误将转到通道 2 = tty1。

当您忽略重定向并通过 shell 提示符运行命令时,通道 1 和通道 2 都会重定向到您唯一的屏幕 (tty0)。

所以只需在你的 shell 中运行

$ command
Run Code Online (Sandbox Code Playgroud)

默认情况下相当于

$ command 1>/dev/tt0 2>/dev/tt0
Run Code Online (Sandbox Code Playgroud)

当我们有一个变量赋值时(就像你的例子),那么游戏就会有点不同。
Shell 创建一个临时位置(如果您愿意,也可以是变量空间)来保存命令生成的正常输出,但默认情况下错误输出不会驱动到该变量。

所以对于像这样的变量赋值

variable=$(command) 
Run Code Online (Sandbox Code Playgroud)

某种程度上等于:

command 1>$variable 2>/dev/tt0    #this is not a valid syntax , it is just an example to demonstrate how different ouputs are handled by default.
Run Code Online (Sandbox Code Playgroud)

错误输出会一直发送到 tty0(您的屏幕),除非您显式地将错误输出重定向到其他地方,例如2>file(将错误发送到文件)或2>&1= 将错误输出发送到正常输出所在的同一位置 => 变量。

考虑这些测试:

echo "hello world" >hello.txt 
#we create a simple file. Channel number is not given but is considered to be 1 by defauly, so this is equivalent to echo "..." 1>hello.txt 
ls -all
> drwx------    2 9925691 root   4096 Dec 13 01:29 .
> drwxr-xr-x 2802 root    root 253952 Dec 13 01:29 ..
> -rw-r--r--    1 9925691 root     12 Dec 13 01:29 hello.txt

a=$(ls -all hello.txt) #variable assignment ignoring the error output
echo "Lets print the contents of variable 'a' : $a"
> Lets print the contents of variable 'a' : -rw-r--r-- 1 9925691 root 12 Dec 13 01:31 hello.txt

echo "one more test"
b=$(ls -all helo.txt) #there is no file helo.txt so this will produce an error
echo "variable 'b' contains: $b"
> one more test
> variable 'b' contains:  #nothing is printed in normal output &1 so the variable is null
> ls: cannot access 'helo.txt': No such file or directory #this error is printed directly to tty0, is not stored in variable "$a" and thus can not be used later on from your scripts.

echo "another test'
c=$(ls -all helo.txt 2>&1)
echo "variable 'c' contains: $c"
> another test
> variable 'c' contains: ls: cannot access 'helo.txt': No such file or directory #Variable $c contains the error output of the command ls.
> #nothing is printed on your screen directly. is all stored in variable "$c"
Run Code Online (Sandbox Code Playgroud)