必须是 2>&1 而不是 1>&2,因为 shell 从左到右解析重定向,& 表示引用文件描述符;2>&1 将 stderr 指向 stdout 当前目标(如 /dev/null),而 1>&2 会将 stdout 错误指向 stderr 目标(通常是终端),导致输出未被静默。

直接用 > /dev/null 2>&1 就能丢掉所有输出,但顺序写错、漏掉 & 或误用 1>&2 都会导致错误信息照常打印——这不是“静默”,而是“假装静默”。
为什么必须是 2>&1 而不是 1>&2
Shell 解析重定向是从左到右执行的:& 表示“引用文件描述符”,不是数字字面量。所以 2>&1 意思是“把 fd 2 指向 fd 1 当前指向的位置”;而 1>&2 是“把 fd 1 指向 fd 2 当前指向的位置”,这通常指向终端,结果就是 stdout 被错误地重定向到 stderr 的目标(比如屏幕),反而让本该丢弃的输出又冒出来。
-
> /dev/null先执行 → fd 1 指向/dev/null -
2>&1再执行 → fd 2 复制 fd 1 的目标,也指向/dev/null - 反过来写
2>&1 > /dev/null→ fd 2 先复制原 fd 1(即终端),再把 fd 1 指向/dev/null,错误照常输出
&> /dev/null 和 > /dev/null 2>&1 有区别吗
功能完全等价,都是把 stdout 和 stderr 合并后丢进黑洞。但 &> 是 Bash 4.0+ 才支持的简写,在老系统(如 CentOS 6 默认的 Bash 3.2)里会报 syntax error near unexpected token `>'。
- 兼容性优先选
> /dev/null 2>&1 - 脚本明确限定 Bash ≥ 4.0 且追求简洁,可用
&> /dev/null -
&>> /dev/null是追加模式,等价于>> /dev/null 2>&1,一般不用——黑洞不需要追加
什么时候不该用 /dev/null 丢输出
丢掉所有输出看似干净,但实际掩盖了关键线索。以下场景建议保留 stderr 或分开处理:
- 调试阶段:命令失败时,
2>/dev/null会让错误消失,你根本不知道它挂了 - 定时任务(
cron):cron 默认把 stderr 发邮件,2>&1后邮件里全是空,不如2> error.log留痕 - 依赖输出做判断的脚本:比如
if ping -c1 google.com > /dev/null 2>&1; then ...可以,但若后续要解析 ping 的延迟值,就不能丢 stdout - 权限不足类错误:像
find /root -name "*.log" > /dev/null 2>&1会吞掉Permission denied,导致你以为没找到文件,其实是没权限
真正容易被忽略的点是:重定向只影响当前命令的 fd 1 和 fd 2,不改变子进程继承的行为;如果命令内部再开新进程(比如 bash -c 'echo hello; ls /root'),它的输出仍受外层重定向约束——但如果你在脚本里用 exec 2>/dev/null,那就会影响后续所有命令,这种全局重定向比单条命令更难追踪。











