重定向 >& 和 &>

2024-06-12 ⏳1.0分钟(0.4千字)

一文带你理解重定向输出以及 >&&> 的用法.

缘起

在写脚本或者调试的时候日志可能太长, 或者需要保留一份日志, 我们可能有把日志写入文件, 或者输出到控制台并写入日志的诉求, 但是老是用错.

go run main.go server --internal > 1.txt 2>&1

go run main.go server --internal 2>&1 > 1.txt ❌

饭前小菜

我们知道Linux下, 文件表述的对应关系如下:

name File_descriptor
标准输入 0
标准输出 1
标准错误 2

详细可以看 wiki 百科File Descriptor.

从头说起

一般来说我们把标准输出写入到文件是:

echo "hello" > 1.txt

如果同时写入标准输出和错误输出到文件:

go run main.go server --internal > 1.txt 2>&1

顺序问题

为什么要把 2>&1 写在 > 1.txt 后面呢? 我们通过 man bash 搜索 order 或者 REDIRECTION 可以看到下面的解释。

Note that the order of redirections is significant. For example, the command

   ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist, while the command

   ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard error was duplicated as standard output before the standard output was redirected to dirlist.

基本上,重定向操作符是从重定向到的地方复制指针,而不是指向其他描述符。因此,重定向的顺序非常重要。

不关心顺序

那能不能不关心顺序呢? 可以!

go run main.go server --internal >& 1.txt

为什么是 >& ? 其实 &> 也是可以的, 继续浏览 man bash, 我们可以看到:

Redirecting Standard Output and Standard Error Bash allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of word with this construct.

There are two formats for redirecting standard output and standard error:

       &>word
and
       >&word

Of the two forms, the first is preferred.  This is semantically equivalent to

       >word 2>&1

小结

>&&> 只是不同的形式而已.