为什么不同的重定向方式命令执行时长会有差异?

为什么不同的重定向方式命令执行时长会有差异?

我正在find以普通用户身份运行定时命令。

我所知道的是,重定向是为了防止终端上出现 stdout/stderr 消息。如果是这样,为什么不同的重定向方法需要不同的时间?它是否与 tty 上的写入速度有关,或者背后是否有其他原因?有人能指出我理解这一点的正确方向吗?

$ id
uid=1000(user1) gid=1000(user1) groups=1000(user1),1001(user2)

$time find /
<truncated output>
real    0m13.902s
user    0m0.197s
sys 0m0.448s

$ time find /  >/dev/null  
<truncated output>
real    0m0.298s
user    0m0.068s
sys 0m0.206s

$time find /  2> /dev/null 
<truncated output>
real    0m13.279s
user    0m0.181s
sys 0m0.405s

$ time find /  > /dev/null 2>&1
real    0m0.306s
user    0m0.109s
sys 0m0.174s

答案1

当您的进程 ( find) 需要实际写出输出时,这显然比您告诉它丢弃所述输出花费的时间要长得多。

  • 当您使用 时find /,stdout 和 stderr 都会发送到您的终端,并且它必须写出它们(即实际结果和所有权限错误等等)

  • 当您使用时,time find / >/dev/null您将删除命令的标准输出,但仍然打印出所有错误(如果有的话)。从您的结果来看,您有很多合法的结果,并且错误很少。

  • 当您使用 时time find / 2> /dev/null,命令的标准输出仍会发送到您的终端,但现在您只需删除 stderr。如果您通过文件系统发现您无权读取,这实际上会非常快。

  • 当您使用 时time find / > /dev/null 2>&1,您将删除标准输出,然后将标准错误发送到发送标准输出的位置,...即,您将删除两者。这不会输出任何内容,因此将是所有命令中最快的。

答案2

我所知道的是,重定向是为了防止终端上出现 stdout/stderr 消息。

好吧,不:您还可以重定向到文件:

find / > ~/all-the-files

它与 tty 上的写入速度有某种关系吗?

总之,是的。

无论您使用哪种终端(Linux 中的虚拟控制台、本地 xterm、通过 SSH 连接的终端),实际的终端模拟器都必须绘制终端上打印的所有内容,即使在这种情况下它会滚动快出来了。 (这里的连接mosh可能是一个例外。)

通过网络连接,还需要考虑传输延迟,一些数据可能会被缓冲,如果有很多数据,而不是全部。如果您将某些内容重定向到/dev/null,它不会保存在任何地方,也不会绘制。对于中等数量的数据,重定向到文件也会很快,因为操作系统可能会将写入内容缓存在内存中,然后才实际延迟写入磁盘。对于大量数据,写入磁盘也可能成为瓶颈。 (或者,如果您设法让进程以同步 I/O 模式写入输出)

对于执行大量输出的程序,printf()即使数据被重定向到/dev/null.在这种情况下,如果您可以说服程序完全禁止输出,速度可能会更快。这可能不是 的情况find,我认为它会受到 I/O 速度或系统调用开销的限制。

另请注意,如果您find重复在同一目录树中运行,第一次可能会比其他次慢,因为第一次可能需要从磁盘读取,而之后,大部分数据将被操作系统缓存。

相关内容