2>&1和&>/dev/null

本文详细解释了Linux中标准输入输出的概念,包括STDIN、STDOUT和STDERR,并通过实例展示了如何使用重定向符号来控制输出流向,比如2>1、2>&1等,还介绍了如何利用/dev/null来捕获不需要的日志输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经常关注linux脚本的人,一定看到过 2>&1这样的用法,最初一定不明白其中的含义以及为什么是这样的一种组合。昨天偶然间再次看到了这个 2>&1的写法,遂下决心搞明白其中的含义。
    其实要弄清楚2>&1的含义,首先应当知道linux中有三种标准输入输出,分别是STDIN,STDOUT,STDERR,对应的数字是0,1,2。STDIN就是标准输入,默认从键盘读取信息;STDOUT是标准输出,默认将输出结果输出至终端,也就是显示器之类的东西;STDERR是标准的错误信息,默认也会显示在终端上。由于STDOUT与STDERR都会默认显示在终端上,为了区分二者的信息,就有了编号的0,1,2的定义,用1表示STDOUT,2表示STDERR。
   下面举个例子:以rhce中的例子为例。
   1、在系统中创建一个普通用户test;
   2、以普通用户登录,或者以root登录 su -test 切换至普通用户test;
    3、执行 find/etc -name passwd命令,默认会将命令的执行结果(STDOUT)与错误信息(STDERR)都输出至终端显示器。
   4、体验一下编号1,2的作用,find /etc -name passwd >find.out2>find.err,这里会将STDOUT与STDERR分别存放至find.out和find.err中,该命令也可以写成下面三种形式,大家可以体会一下编号的意义。
    find /etc-name passwd 1>find.out 2>find.err
    find /etc-name passwd 2>find.err >find.out
    find /etc-name passwd 2>find.err 1>find.out
    我个人理解就是find/etc -namepasswd的命令的执行结果输出正确的输出(STDOUT)被1接收,错误的信息(STDERR)被2接收。
   5、若要将所有的输出及错误信息都显示出来,可以用&表示全部1和2的信息,例如:
    find /etc-name passwd &>find.all
   6、有时候希望将错误的信息重新定向到输出,就是将2的结果重定向至1中就有了"2>1"这样的思路,如果按照上面的写法,系统会默认将错误的信息(STDERR)2重定向到一个名字为1的文件中,而非所想的(STDOUT)中。因此需要加&进行区分。就有了2>&1 这样的用法,举例:
    find /etc-name passwd 2>&1 |less
   7、有时候还能看到这样的用法:
    find /etc-name passwd &2>&1 |less
   这里可以分解成
    find /etc-name passwd&   表示前面的命令放到后台执行。
 
   2>&1|less   表示将错误信息重定向至标准输出,并用less进行分页显示
 
-----------------------------------------------------------------------------------

/dev/null看作"黑洞". 它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而,/dev/null对命令行和脚本都非常的有用.

禁止标准输出.

1 cat $filename >/dev/null
   2 # 文件内容丢失,而不会输出到标准输出.

禁止标准错误

1 rm $badname 2>/dev/null
   2 #           这样错误信息[标准错误]就被丢到太平洋去了.

禁止标准输出和标准错误的输出.

1 cat $filename 2>/dev/null >/dev/null
   2 # 如果"$filename"不存在,将不会有任何错误信息提示.
   3 # 如果"$filename"存在, 文件的内容不会打印到标准输出.
   4 # 因此Therefore, 上面的代码根本不会输出任何信息.
   5 # 当只想测试命令的退出码而不想有任何输出时非常有用。
   6 #-----------测试命令的退出 begin ----------------------#
   7 # ls dddd 2>/dev/null 8 
   8 # echo $?    //输出命令退出代码:0为命令正常执行,1-255为有出错。  
   9 #-----------测试命令的退出 end-----------#  
   10# cat $filename &>/dev/null 
   11 #   也可以, 由 Baris Cicek 指出.


有的时候你查找文件的时候很容易产生无用的信息,如:2> /dev/null的作用就是不显示标准错误输出;另外当你运行某些命令的时候,出错信息也许很重要,便于你检查是哪出了毛病,如:2>&1

----------------------------------------------------------------
实用总结

如果在编译代码的时候想看全部log,在输出的终端上找是非常不方便的,在编译完源码后想看编译时输出的log,最好的方法就是让所有输出(标准输出1和标准错误输出2)都存储在mybuild.log里。
为此可以这样实现:
./build.sh 2>&1 | tee mybuild.log        ##tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
这样我们既可以在终端实时查看当前的编译log,有可以讲屏幕上的输出重定向到mybuild.log文件当中。
----------------------------------------------------------------
若不了解tee命令,想了解tee命令请看如下说明:
linux tee 命令详解
功能说明:读取标准输入的数据,并将其内容输出成文件。

语  法:tee [-ai][--help][--version][文件...]

补充说明:tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。

参  数:
 -a或--append  附加到既有文件的后面,而非覆盖它.
 -i-i或--ignore-interrupts  忽略中断信号。
 --help  在线帮助。
 --version  显示版本信息。
 
 
[root@localhost ~]# who | tee who.out
root     pts/0        2009-02-17 07:47 (123.123.123.123)
[root@localhost ~]# cat who.out
root     pts/0        2009-02-17 07:47 (123.123.123.123)
[root@localhost ~]# pwd | tee -a who.out
/root
[root@localhost ~]# cat who.out
root     pts/0        2009-02-17 07:47 (123.123.123.123)
/root
[root@localhost ~]#

<think>我们正在讨论命令行中的重定向操作符 `> /dev/null 2>&1`。根据用户提供的引用内容,我们可以总结如下: 1. `/dev/null` 是一个特殊的设备文件,它像一个“黑洞”,写入它的任何内容都会被丢弃,读取它会立即得到EOF(文件结束符)[^4]。 2. 在命令行中,`>` 是重定向操作符,默认重定向标准输出(文件描述符1)。所以 `> /dev/null` 等同于 `1> /dev/null`,表示将命令的标准输出重定向到 `/dev/null`,即丢弃标准输出[^2][^3]。 3. `2>&1` 表示将标准错误(文件描述符2)重定向到标准输出(文件描述符1)的当前位置。由于之前标准输出已经被重定向到 `/dev/null`,所以标准错误也会被重定向到 `/dev/null`,即也被丢弃[^2][^3]。 4. 因此,整个表达式 `> /dev/null 2>&1` 的作用是:同时丢弃命令的标准输出标准错误输出。 现在,让我们详细解释一下: - **标准输出(stdout)**:文件描述符为1,通常是命令的正常输出。 - **标准错误(stderr)**:文件描述符为2,通常是命令的错误信息。 - 重定向的顺序很重要:`2>&1` 必须写在 `> /dev/null` 后面,因为它是将标准错误重定向到当前标准输出的位置(即已经重定向到`/dev/null`的状态)。如果顺序颠倒,比如 `2>&1 >/dev/null`,那么标准错误会先被重定向到标准输出(此时还是终端),然后标准输出再被重定向到`/dev/null`,这样标准错误就会仍然输出到终端。 所以,`> /dev/null 2>&1` 的完整含义是: 1. 将标准输出重定向到 `/dev/null`(丢弃)。 2. 将标准错误重定向到标准输出当前的位置(即 `/dev/null`),因此标准错误也被丢弃。 这样,命令执行后,既不会在终端看到正常输出,也不会看到错误信息。 另外,用户还提到了在命令末尾加上 `&` 的情况,例如: ```bash command > /dev/null 2>&1 & ``` 这里的 `&` 表示将命令放入后台执行,这样命令行会立即返回,不会等待命令执行完成[^3]。 总结: - `> /dev/null`:丢弃标准输出。 - `2>&1`:将标准错误重定向到标准输出(此时标准输出已经指向`/dev/null`,所以标准错误也被丢弃)。 - 组合:`> /dev/null 2>&1` 表示丢弃所有输出(包括标准输出标准错误)。 - 末尾的 `&`:将命令放入后台执行。 现在,我们可以根据用户的问题,给出一个清晰的结构化回答。</think>在命令行中,`> /dev/null 2>&1` 是一个**输出重定向组合**,其作用是将命令的所有输出(包括正常输出错误信息)完全丢弃。以下是详细解释: ### 1. 核心组件解析 | 组件 | 含义 | 文件描述符 | |------|------|------------| | `/dev/null` | Linux 的"黑洞"设备,丢弃所有写入的数据 | - | | `>` 或 `1>` | 标准输出重定向(stdout) | 文件描述符 1 | | `2>&1` | 将标准错误(stderr)重定向到 stdout | 文件描述符 2 | ### 2. 执行顺序解析(关键!) 1. **`> /dev/null`** → 先将标准输出(stdout)重定向到 `/dev/null`(丢弃正常输出) 2. **`2>&1`** → 再将标准错误(stderr)重定向到**当前 stdout 的位置**(即 `/dev/null`) → 错误信息也被丢弃 ### 3. 实际效果 ```bash your-command > /dev/null 2>&1 ``` - ✅ **无任何输出**:命令的所有输出(正常结果+错误信息)都被丢弃 - ✅ **无文件生成**:不会在磁盘创建任何输出文件 - ❌ **无调试信息**:不适合需要查看错误的场景 ### 4. 常见使用场景 1. **后台静默执行** ```bash nohup your-server > /dev/null 2>&1 & ``` - 服务后台运行,不产生日志文件 - 终端关闭后进程继续运行 2. **定时任务** ```bash # 每天备份数据库,不发送通知邮件 0 3 * * * /backup.sh > /dev/null 2>&1 ``` 3. **抑制干扰信息** ```bash # 安装软件时隐藏冗长的输出 apt install package -y > /dev/null 2>&1 ``` ### 5. 与其他写法的区别 | 命令 | 效果 | |------|------| | `> out.log 2>&1` | 所有输出写入 out.log | | `2>&1 > /dev/null` ❌ | 错误仍显示(顺序错误!) | | `> /dev/null` | 仅丢弃正常输出,错误仍显示 | | `2> /dev/null` | 仅丢弃错误信息,正常输出仍显示 | > ⚠️ **顺序至关重要**:`2>&1` 必须放在重定向目标**之后**,否则无效[^2][^3]。 ### 6. 文件描述符原理 ```mermaid graph LR A[命令执行] --> B[stdout 文件描述符1] A --> C[stderr 文件描述符2] B --> D[/dev/null黑洞] C -->|2>&1| B ``` 通过这个组合,系统将标准输出标准错误都路由到同一个"黑洞"设备,实现完全静默执行[^1][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值