Loading

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

 

参考:

知乎 - 如何理解Linux shell中的“2>&1”

shell 脚本中获取命令的输出_歪歪的酒壶的博客-CSDN博客_shell获取命令输出结果

posted @ 2020-12-30 16:10  拾月凄辰  阅读(2284)  评论(0编辑  收藏  举报