Linux中 2>&1 的含义
文件描述符
每个进程拥有自己的标准输入流、标准输出流、标准错误流。这几个标准流说起来很复杂,但其实都是文件。
- 标准输入流(用 0 表示)可以作为进程执行的上下文(进程执行可以从输入流中获取数据)。
- 标准输出流(用 1 表示)中写入的结果会被打印到屏幕上。
- 如果进程在执行过程中发生异常,那么异常信息会被记录到标准错误流(用 2 表示)中。
例子
看一个例子,比如我们输入:
ls1 > out
结果并不会存入out文件,因为ls1指令是不存在的。结果会输出到标准错误流中,仍然在屏幕上。这里我们可以把标准错误流也重定向到标准输出流,然后再重定向到文件。
ls1 &> out
这个写法等价于:
ls1 > out 2>&1
2>&1的含义
2>&1表明将文件描述2(标准错误输出)的内容重定向到文件描述符1(标准输出),为什么1前面需要&?当没有&时,1会被认为是一个普通的文件,有&表示重定向的目标不是一个文件,而是一个文件描述符。
为何2>&1要写在后面?
command > file 2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。
command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但标准错误仍然保持在终端。
测试
##测试不加&号 $ ls1 > out 2>1 $ ls 1 $ cat 1 bash: ls1: command not found... ##测试2>&1放在中间 $ ls1 2>&1 > out bash: ls1: command not found... ##测试2>&1放在结尾 $ ls1 > out 2>&1 $ ls 1 out $ cat out bash: ls1: command not found...
应用场景
test.sh:
#!/bin/bash check_result=`iscsiadm --version` echo "check_result : $check_result"
此时,如果 iscsiadm 命令不存在,则check_result 的值会为空,错误信息会打印到标准输出流中,如下:
[root@host130 workspace]# ./test.sh ./test.sh: line 3: iscsiadm: command not found check_result :
如果想让错误信息也保存到check_result变量中,那在命令末尾加上 2>&1 即可。
test1.sh:
#!/bin/bash
check_result=`iscsiadm --version 2>&1`
echo "check_result : $check_result"
输出结果:
[root@host130 workspace]# ./test1.sh check_result : ./test1.sh: line 3: iscsiadm: command not found