Mor*_*gan 18 io-redirection devices
这里的大多数答案[ 1 ] [ 2 ] [ 3 ]使用单个尖括号重定向到 /dev/null,如下所示:
command > /dev/null
Run Code Online (Sandbox Code Playgroud)
但附加到 /dev/null 也有效:
command >> /dev/null
Run Code Online (Sandbox Code Playgroud)
除了额外的字符,有什么理由不这样做吗?这些中的任何一个对 /dev/null 的底层实现“更好”吗?
编辑:
在开放式(2)手册页说lseek的是每次写在附加模式文件之前名为:
O_APPEND
文件以追加模式打开。在每次 write(2) 之前,文件偏移量位于文件末尾,就像使用 lseek(2) 一样。文件偏移的修改和写入操作作为单个原子步骤执行。
这让我认为使用>>
. 但另一方面,根据该文档,截断 /dev/null 似乎是一个未定义的操作:
O_TRUNC
如果文件已经存在并且是一个常规文件并且访问模式允许写入(即,是 O_RDWR 或 O_WRONLY),它将被截断为长度 0。如果文件是 FIFO 或终端设备文件,则忽略 O_TRUNC 标志。否则,未指定 O_TRUNC 的效果。
并且 POSIX 规范说>
应该 truncate an existing file,但是O_TRUNC 是为设备文件实现定义的,并且没有关于 /dev/null 应该如何响应被截断的消息。
那么,截断 /dev/null 实际上是未指定的吗?并做lseek的来电对写性能产生任何影响?
ilk*_*chu 28
根据定义,/dev/null
写入的任何内容都会下沉,因此无论您是否以追加模式写入,都将被丢弃。因为它不存储数据,所以没有什么可附加的,真的。
所以最后,> /dev/null
用一个>
符号写的时间更短。
至于编辑后的补充:
open(2) 联机帮助页说在每次以追加模式写入文件之前都会调用 lseek。
如果你仔细阅读,你会看到它说(强调我的):
文件偏移量位于文件末尾,就像使用lseek(2)
意思是,它实际上并不(需要)调用lseek
系统调用,而且效果也不完全相同:lseek(fd, SEEK_END, 0); write(fd, buf, size);
不调用O_APPEND
与追加模式下的写入不同,因为通过单独的调用,另一个进程可以写入文件在系统调用之间,删除附加的数据。在追加模式下,这不会发生(除了通过NFS,它不支持真正的追加模式)。
标准中的文本在这一点上没有提到lseek
,只有写入应该到文件的末尾。
那么,截断 /dev/null 实际上是未指定的吗?
从你所引用的经文来看,显然它是由实现定义的。这意味着任何理智的实现都将与管道和 TTY 一样,即什么都没有。一个疯狂的实现可能会做其他事情,并且截断可能意味着在某些其他设备文件的情况下是明智的。
lseek 调用对写入性能有任何影响吗?
测试一下。这是在给定系统上确定的唯一方法。或者阅读源代码以查看附加模式在何处更改行为(如果有)。