哪个更好?
cmd >>file 2>&1
cmd 1>>file 2>>file
它们之间有区别吗?
我知道选择第一个的两个原因:它也可以使用>
代替>>
。它更流行,因此熟悉shell脚本的人会立即理解。
但是,我仍然觉得第二种方式更易读,并且不需要了解[n]>&[n]
语法,这对我来说有点困惑。
哪个更好?
cmd >>file 2>&1
cmd 1>>file 2>>file
它们之间有区别吗?
我知道选择第一个的两个原因:它也可以使用>
代替>>
。它更流行,因此熟悉shell脚本的人会立即理解。
但是,我仍然觉得第二种方式更易读,并且不需要了解[n]>&[n]
语法,这对我来说有点困惑。
让我们来看一下每个命令的含义。我将假设问题没有提出更具体的要求,因此适用POSIX shell规范。
第一个命令是cmd >>file 2>&1
。在设置指定的重定向后运行cmd
。
重定向>>file
使用O_APPEND
打开指定的文件。如open
的规定所述,这创建了一个新的打开文件描述符,其中特别包含当前文件偏移量,并安排文件描述符 1引用该描述符。 O_APPEND
的含义是“在每次写入之前,文件偏移量将设置为文件末尾”。
重定向2>&1
表示文件描述符2“将变成文件描述符1的副本”。该规范有点模糊,但我认为唯一合理的解释(以及shell实际上的做法)是它意味着调用dup2(1, 2)
,它“将导致文件描述符[2]引用与文件描述符[1]相同的打开文件描述符”。至关重要的是,我们获得另一个文件描述符,但继续使用同一个文件描述符,这意味着它们都具有相同的文件偏移量。
第二个命令是cmd 1>>file 2>>file
。基于上述引用的规范,这会为file
创建两个单独的文件描述符,每个都具有自己的偏移量。
cmd
对文件描述符1和2唯一要做的事情就是调用write
,那么这两种情况是等效的,因为每次对write
的调用将在执行写操作之前原子地更新偏移量,因此第二个命令中存在两个独立的偏移量不会有任何可观察的影响。cmd
执行其他操作,例如lseek
,则这两种情况是不等价的,因为这将显示第一个命令具有一个共享偏移量,而第二个命令具有两个独立偏移量。O_APPEND
的POSIX规定语义。但是真实的计算机系统并不总是实现它;例如,NFS没有原子追加。在没有原子追加的情况下,即使只进行write
,第二个命令也可能表现出不同的行为(最有可能损坏输出)。cmd
的标准输出和标准错误附加到file
中,假定cmd
只向这些描述符中写入内容。这正是第一个命令的含义(cmd >>file 2>&1
),因此是更好的选择。
cmd 1>>outfile 2>>errfile
(这是使用两个描述符的唯一好处) - David C. Rankin&>>
(bash)或>>&
(tcsh)。 - Davis Herring&>>
(只有&>
,>>
, 和>&
),一些人仍然没有这个功能(参考链接:https://stackoverflow.com/q/30708549/8586227)。 - Davis Herring