Linux shell : Command 2>&1

之前看到如下shell 命令,一头雾水:


ls temp >list.txt  2>&1
ls temp >/dev/null  2>&1


查阅之后,明白此语句含义,特此记录.


首先说明几点:

  1. 在unix和类unix(linux之类)中以文件描述符的形式打开一个文件,这个文件描述符是一个非负数。
  2. 0代表标准输入,1代表标准输出,2代表标准错误输出
  3. 默认的情况下是1 所以  > 相当于 1> 
  4. shell命令的执行是从左往右

ls temp >list.txt  2>&1     (ps:temp是个不存在的目录)
ls temp >list.txt  :
把标准输出重定向到list.txt文件中,在这里,就是把temp目录下所有的文件,列出来,然后输出到list.txt文件
如果没有这个重定向,那么标准输出默认是控制台
标准输出的句柄应该是1 ,所以,完整的写法应该是:ls temp 1>list.txt 


2>&1  :
在此处 ,表示把标准错误输出写入到list.txt文件
经过这个重定向,标准输出和标准错误输出都重定向到了list.txt中
结果如下:
root:ls temp >list.txt  2>&1 
root:/opt/tmp # more list.txt 
ls: cannot access temp: No such file or directory   //error 信息在文件里


ls temp >/dev/null  2>&1 

这个表示把标准输出,以及标准错误输出都舍弃了,不显示也不保存


如果换一下顺序,如何?
ls temp 2>&1 >list.txt  
标准错误输出定向到控制台,标准内容输出定向到list.txt 
结果如下:
root:/opt/tmp # ls temp 2>&1 >out.txt
ls: cannot access temp: No such file or directory  //error信息直接输出到控制台


总结:
ls temp :表示标准内容输出和标准错误都输出到控制台 
         等同于:ls temp>&1 
ls temp >list :表示标准内容输出到list文件中,标准错误输出还是在控制台
        等同于:ls temp 1>list
ls temp >list   2>&1 :表示标准内容输出到list文件中,标准错误输出也在list文件中 
        等同于:ls temp >list   2>list
                        ls temp 1>list  2>list
                        ls temp 1>list   2>&1

ls temp  2>&  >list :标准错误输出也在控制台,表示标准内容输出到list文件中
        等同于:ls temp  2>&  1>list                     




参考文献:
http://www.cnblogs.com/caolisong/archive/2007/04/25/726896.html
http://www.ningoo.net/html/2007/shell_scripts_stderr_stdout.html

<think>好的,我现在需要解释用户关于Linux重定向的两个命令的区别:`command > file 2>&1` 和 `command 2>&1 > file`。用户之前已经询问过重定向的基础知识,现在深入到了具体的语法顺序问题。我得先回忆一下文件描述符重定向的工作原理,特别是顺序对结果的影响。 首先,用户可能已经知道标准输出(1)和标准错误(2)的区别,以及如何分别重定向它们。但这两个命令看起来相似,只是顺序不同,结果却大不一样。我需要明确每个步骤发生了什么。 对于`command > file 2>&1`,首先将标准输出重定向到file,然后将标准错误指向标准输出当前的位置,也就是file。所以两个输出都会写入file。 而`command 2>&1 > file`,这里首先将标准错误重定向到标准输出的原位置(即终端),然后才把标准输出重定向到file。因此,标准错误仍然输出到终端,标准输出到file。这显然不是用户通常想要的结果,容易造成误解。 我需要用例子来说明这两个命令执行后的结果差异。比如,当command产生正常输出和错误时,第一个命令将所有内容写入file,而第二个命令错误显示在终端,正常输出到file。这时候用户可能会疑惑为什么顺序不同导致结果不同,可能需要解释shell处理重定向的顺序是从左到右的,每一步改变当前的文件描述符指向。 另外,需要注意语法中的符号顺序,比如`2>&1`和`> file`的位置,以及它们如何影响后续的重定向。可能还需要提到`&>`这种更简洁的写法,避免顺序错误。 还要考虑用户可能的误区,比如认为`2>&1`总是指向同一个目标,但实际上它是指向当前标准输出的位置,而如果在之后又改变了标准输出,错误输出不会自动跟随。这时候顺序就变得非常关键。 总结时,要强调顺序的重要性,并给出最佳实践,比如使用`&>`或者确保先重定向标准输出再复制文件描述符。同时提醒用户注意常见的错误,比如在脚本中错误排列顺序导致日志不完整。</think>在 Linux 中,`command > file 2>&1` 和 `command 2>&1 > file` 虽然看起来相似,但**执行顺序不同会导致完全不同的结果**。关键在于文件描述符的重定向是**从左到右逐句解析**的。 --- ### **1. `command > file 2>&1` 的流程** 1. **第一步**:`> file` 将标准输出(文件描述符 `1`)重定向到 `file`(覆盖写入)。 2. **第二步**:`2>&1` 将标准错误输出(文件描述符 `2`)**指向当前标准输出的位置**(即 `file`)。 **最终效果**: - 标准输出(正常结果)和标准错误(错误信息)**均写入 `file`**。 --- ### **2. `command 2>&1 > file` 的流程** 1. **第一步**:`2>&1` 将标准错误输出(`2`)指向**当前标准输出的位置**(此时标准输出默认指向终端屏幕)。 2. **第二步**:`> file` 将标准输出(`1`)重定向到 `file`(覆盖写入),但**标准错误(`2`)仍然指向终端**(因为第一步的 `2>&1` 已绑定到初始的标准输出)。 **最终效果**: - 标准输出(正常结果)写入 `file`。 - 标准错误(错误信息)**仍输出到终端**。 --- ### **直观对比** | 命令 | 标准输出(`1`) | 标准错误(`2`) | 结果 | |------------------------|----------------|----------------|-----------------------------------| | `command > file 2>&1` | 写入 `file` | 也写入 `file` | 所有输出(正常+错误)存入文件 | | `command 2>&1 > file` | 写入 `file` | 输出到终端 | 仅正常结果存入文件,错误仍显示在屏幕 | --- ### **示例验证** 假设有一个脚本 `test.sh`,同时输出正常内容和错误信息: ```bash echo "这是正常输出" # 标准输出(1) ls /nonexistent # 故意触发错误(标准错误 2) ``` #### 执行 `> file 2>&1`: ```bash ./test.sh > output.log 2>&1 ``` - **`output.log` 内容**: ``` 这是正常输出 ls: cannot access '/nonexistent': No such file or directory ``` #### 执行 `2>&1 > file`: ```bash ./test.sh 2>&1 > output.log ``` - **终端显示错误**: ``` ls: cannot access '/nonexistent': No such file or directory ``` - **`output.log` 内容**: ``` 这是正常输出 ``` --- ### **为什么顺序如此重要?** Shell 解析重定向时是**从左到右逐步绑定**的: 1. 每个重定向操作会修改当前文件描述符的指向。 2. `2>&1` 的含义是“将文件描述符 2 指向文件描述符 1 **当前**的位置”,而不是“永久跟随文件描述符 1”。 --- ### **最佳实践** - **合并输出和错误到文件**: 直接使用更简洁的 `&>` 或 `&>>`(追加模式): ```bash command &> file # 覆盖写入 command &>> file # 追加写入 ``` - **显式写法**: 若需兼容性更强,优先使用 `> file 2>&1`。 --- ### **总结** - `command > file 2>&1`:**所有输出**(正常+错误)写入文件。 - `command 2>&1 > file`:仅**正常输出**写入文件,**错误仍显示在终端**。 **核心区别在于重定向的解析顺序**,务必注意文件描述符的“当前指向”特性。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值