为什么附加到日志文件是 2>&1 而不是 2>>&1

Mik*_*rgy 46 bash shell redirection stderr append

我将 STDOUT 和 STDERR 重定向到一个文件,并且一直在增长,所以我总是使用“附加”重定向;这是>>

我的命令是 command >> logfile 2>&1

它有效。

但是 STDERR 重定向有一个>,我用它来“创建”文件,擦除前一个文件,如command > outlog 2> errlog

为什么在这种情况下它不删除日志文件?

use*_*686 57

当您将某些内容重定向到 时,您根本没有打开新文件;您正在重用已经打开的文件以及它打开的任何模式。&number

这些数字指的是“打开文件”句柄(文件描述符)。因此,>&>>&(实际上<&)的工作方式之间没有技术差异——它们都只是意味着“使用 dup() 克隆现有的文件描述符”。

也就是说,2>&1表示文件描述符 #1(您之前打开使用追加>>logfile)被克隆到编号 #2。是的,2<&1工作原理相同。

附带技术说明:追加与截断不是 shell 执行的显式操作;它实际上是 shell在打开文件指定的一种模式,其余的由操作系统本身执行。例如,当您使用>shell 时不会手动擦除旧内容,它只是在调用 open() 时添加 O_TRUNC。因此,当根本没有调用 open(),之前的模式保持不变。

  • @barlop:是的;不_完全_,但非常相似。如果您在原始 Win32 API 上进行开发,则 CreateFile() 函数具有 TRUNCATE_EXISTING,这与 POSIX open() 的 O_TRUNC 含义相同,并且您具有 DuplicateHandle(),它类似于 dup(),即使 Windows 的 stdin/stdout有点奇怪,更特殊。(如果你在 Mingw 上开发,你只会得到相同的 POSIX open()。大多数更高级别的 I/O 库,如 C stdio 或 Python io,都有诸如“w”“a”“r+”之类的模式,它们直接转换为同样的事情。) (7认同)

Eug*_*eck 14

该序列command >> logfile 2>&1有两个重定向阶段:

  • command >> logfile 将附加到日志文件
  • 2>&1将标准错误重定向到标准输出(它本身附加到日志文件)

所以command >> logfile 2>&1不会截断日志文件,而command >>logfile 2>logfile会。

  • 不,类 Unix 系统上的文件不仅仅通过打开来锁定。(就此而言,例如 Linux 根本不支持强制锁定。_) (7认同)