考虑像Bash或sh这样的shell。在目标文件存在的情况下,>
和之间的基本区别在于>>
:
>
将文件截断为零大小,然后写入;>>
不截断,它写入(附加)到文件的末尾。
如果文件不存在,则会以零大小创建文件;然后写。对于两个运营商都是如此。当目标文件尚不存在时,这些运算符似乎等效。
是真的吗
考虑像Bash或sh这样的shell。在目标文件存在的情况下,>
和之间的基本区别在于>>
:
>
将文件截断为零大小,然后写入;>>
不截断,它写入(附加)到文件的末尾。如果文件不存在,则会以零大小创建文件;然后写。对于两个运营商都是如此。当目标文件尚不存在时,这些运算符似乎等效。
是真的吗
Answers:
编号>>
本质上是“始终寻求文件结尾”,同时>
保持指向最后写入位置的指针。
(注意:我所有的测试都是在Debian GNU / Linux 9上完成的)。
不,它们不是等效的。还有另一个区别。无论目标文件之前是否存在,它都可能显示出来。
要观察它,请运行一个生成数据的过程,然后使用>
或>>
(例如pv -L 10k /dev/urandom > blob
)将其重定向到文件。让它运行并更改文件的大小(例如,使用truncate
)。您将看到>
其偏移量(不断增加),而>>
始终附加到末尾。
>
不在乎,它将以所需的偏移量写入,好像什么也没发生;截断偏移量刚好超出文件末尾之后,这将导致文件重新获得其旧大小并进一步增长,丢失的数据将填充零(如果可能的话,采用稀疏方式);>>
将追加到新的末尾,文件将从其截断的大小开始增长。>
不在乎,它将以所需的偏移量写入,好像什么也没发生;更改大小后,偏移量刚好在文件内的某个位置,这将导致文件停止增长一段时间,直到偏移量达到新的末端为止,然后文件将正常增长;>>
将添加到新的末尾,文件将从其放大的大小开始增长。另一个示例是>>
在数据生成过程正在运行并写入文件时,附加一些内容(带有单独的)。这类似于放大文件。
>
将以其所需的偏移量写入并最终覆盖多余的数据。>>
将跳过新数据并追加到新数据之后(竞争条件可能会发生,两个流可能会交错,但仍然不应覆盖任何数据)。在实践中有关系吗?有这个问题:
我正在运行一个在stdout上产生大量输出的进程。将其全部发送到文件[...]我可以使用某种日志轮换程序吗?
这个答案说解决方案是logrotate
带有如下copytruncate
选项的选项:
创建副本后,将原日志文件截断到位,而不是移动旧日志文件并选择创建新的日志文件。
根据我在上面写的内容,使用重定向>
将立即使截断的日志变大。稀疏性可以节省一天的时间,不应浪费大量的磁盘空间。但是,每个连续的日志中将有越来越多的前导零,这是完全没有必要的。
但是,如果logrotate
创建副本时不保留稀疏性,则每次创建副本时,这些前导零将需要越来越多的磁盘空间。我还没有研究过工具的行为,它在稀疏或动态压缩的情况下(如果启用了压缩)可能足够聪明。零仍然可能只会造成麻烦或充其量是中立的。他们没有什么好。
在这种情况下,即使将要创建目标文件,使用>>
代替>
也会更好。
如我们所见,这两个运算符不仅在开始时表现不同,而且在以后表现不同。这可能会导致一些(微妙的)性能差异。目前,我没有有意义的测试结果来支持或反对它,但是我认为您不应该自动假定它们的性能大致相同。
O_APPEND
与lseek()
各前write()
会有所不同,虽然有会是额外的系统调用的开销。(当然,这是行不通的,因为可能会write()
在另一个过程之间进行。)
>>
,在>
保持指向最后写入位置的指针的同时,本质上是“始终寻求文件结尾” 。似乎有可能是他们的工作以及方式有些细微的性能差异...