https://blog.csdn.net/zhaominpro/article/details/82630528
https://zhuanlan.zhihu.com/p/47765176
A.首先了解下1和2在Linux中代表什么?
在Linux系统中0 1 2是一个文件描述符
名称 代码 操作符 Java中表示 Linux 下文件描述符(Debian 为例)
标准输入(stdin) 0 < 或 << System.in /dev/stdin -> /proc/self/fd/0 -> /dev/pts/0
标准输出(stdout) 1 >, >>, 1> 或 1>> System.out /dev/stdout -> /proc/self/fd/1 -> /dev/pts/0
标准错误输出(stderr) 2 2> 或 2>> System.err /dev/stderr -> /proc/self/fd/2 -> /dev/pts/0
从上表看的出来,我们平时使用的
echo "hello" > t.log
其实也可以写成
echo "hello" 1> t.log
B.关于2>&1的含义
含义:将标准错误输出重定向到标准输出
符号>&是一个整体,不可分开,分开后就不是上述含义了。
比如有些人可能会这么想:2是标准错误输入,1是标准输出,>是重定向符号,那么"将标准错误输出重定向到标准输出"是不是就应该写成"2>1"就行了?是这样吗?
如果是尝试过,你就知道2>1的写法其实是将标准错误输出重定向到名为"1"的文件里去了
写成2&>1也是不可以的
例子:
有时候我们常看到类似这样的脚本调用:
./test.sh > log.txt 2>&1
这里的2>&1是什么意思?该如何理解?
先说结论:上面的调用表明将./test.sh的输出重定向到log.txt文件中,同时将标准错误也重定向到log.txt文件中。
假如有脚本test.sh:
#!/bin/bash
date #打印当前时间
while true #死循环
do
#每隔2秒打印一次
sleep 2
whatthis #不存在的命令
echo -e "std output"
done
脚本中先打印当前日期,然后每隔2秒执行whatthis并打印一段字符。由于系统中不存在whatthis命令,因此执行会报错。
假如我们想保存该脚本的打印结果,只需将test.sh的结果重定向到log.txt中即可:
./test.sh > log.txt
执行结果如下:
ubuntu$ ./test.sh >log.txt
./test.sh: 行 7: whatthis: 未找到命令
我们明明将打印内容重定向到log.txt中了,但是这条错误信息却没有重定向到log.txt中。如果你是使用程序调用该脚本,当查看脚本日志的时候,将会完全看不到这条错误信息。而使用下面的方式则会将出错信息也重定向到log.txt中:
./test.sh > log.txt 2>&1
以这样的方式调用脚本,可以很好的将错误信息保存,帮助我们定位问题。
那么现在就容易理解前面的疑问了,2>&1表明将文件描述2(标准错误输出)的内容重定向到文件描述符1(标准输出),为什么1前面需要&?当没有&时,1会被认为是一个普通的文件,有&表示重定向的目标不是一个文件,而是一个文件描述符。在前面我们知道,test.sh >log.txt又将文件描述符1的内容重定向到了文件log.txt,那么最终标准错误也会重定向到log.txt。