$ time (exec -a foo echo hello)
hello
似乎stderr
(在哪里time
写入其输出)在某处泄漏;显然这不是我的本意。
我的问题可以笼统地表述为“当子shell 执行另一个程序时,为什么终端上没有写入标准错误流? ”。
几点注意事项:
- 我需要使用
exec
它的-a
开关,它改变了进程的第零个参数。我希望有一个替代方法exec
来做到这一点,但我不知道,现在这种行为让我很好奇。 - 当然,我需要一个子shell,因为我希望我的脚本继续。同样,任何替代方案都将受到欢迎。在子shell中甚至是
exec
一件好事吗? time
'ing 一个 subshell 通常工作正常,所以它确实与exec
.
有人能指出我正确的方向吗?我不确定在任何参考资料中从哪里开始,exec
描述非常简洁。
更新: 实际上,我只是“幸运”,因为time
这里是内置的 bash。它根本不使用/usr/bin/time
或使用任何其他进程进行解析:
$ env (exec -a foo echo hello)
bash: syntax error near unexpected token `exec'
实际上这是有道理的,我们不能将 subshell 作为参数传递。知道如何以其他方式做到这一点吗?
更新: 总而言之,我们在这里有四个很好的答案,都是不同的,并且可能缺少一些东西:
使用 bash 默认和
time
正常使用的实际文件系统链接(硬链接或符号链接)。归功于 hek2mgl。ln $(which echo) foo && time ./foo hello && rm foo
fork
用于time
使用 bash 和exec
使用没有特殊语法的 bash 子shell。time bash -c 'exec -a foo echo hello'
fork
使用time
bash 但exec
使用了一个小包装器。time launch -a foo echo hello
fork
以及exec
使用time
具有特殊语法的 bash。归功于 sjnarv。time { (exec -a foo echo hello); }
我认为解决方案 1 的影响较小,time
因为计时器不必exec
在“代理”程序中计算,但不是很实用(许多文件系统链接),在技术上也不理想。在所有其他情况下,我们实际上是exec
两次:一次加载代理程序(2 和 4 的子shell,3 的包装器),一次加载实际程序。这意味着time
将计算第二个exec
。虽然它可能非常便宜,exec
但实际上文件系统查找可能非常慢(特别是如果它通过 搜索PATH
,无论是本身exec*p
还是代理进程)。
因此,唯一干净的方法(就该问题的答案而言)是修补 bash 以修改其time
关键字,以便它可以exec
同时将第零个参数设置为非零值。它可能看起来像time -a foo echo hello
。