![为什么不同的重定向方式命令执行时长会有差异?](https://linux22.com/image/112468/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%90%8C%E7%9A%84%E9%87%8D%E5%AE%9A%E5%90%91%E6%96%B9%E5%BC%8F%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E6%97%B6%E9%95%BF%E4%BC%9A%E6%9C%89%E5%B7%AE%E5%BC%82%EF%BC%9F.png)
我正在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
重复在同一目录树中运行,第一次可能会比其他次慢,因为第一次可能需要从磁盘读取,而之后,大部分数据将被操作系统缓存。