【发布时间】:2018-11-09 17:58:16
【问题描述】:
假设我有一个程序foo 可以同时打印到stderr 和stdout。我希望能够计时并将tee 输出到日志文件。
节目说明
我可以拨打foo如下:
user$ time ./foo
这给出(例如)两个流的输出:
标准输出:
stdout says hi
标准错误:
stderr says hi
结合标准错误和标准输出
我可以使用 BASH I/O 重定向轻松地将它们组合成标准输出:
user$ ./foo 2>&1
这给出了以下输出:
标准输出:
stdout says hi
stderr says hi
stderr:(空!)
使用tee
我可以使用tee捕获程序的组合输出:
user$ ./foo 2>&1 | tee log.txt
标准输出:
stdout says hi
stderr says hi
stderr:(空!)
log.txt:
stdout says hi
stderr says hi
使用time 捕获时间
我可以使用 BASH 的内置 time 命令来计时我的程序的执行同时结合标准输出和标准错误:
user$ time ./foo 2>&1
标准输出:
stdout says hi
stderr says hi
标准错误::
real 0m0.017s
user 0m0.003s
sys 0m0.004s
我可以按照here 的描述捕获time 命令的输出并将其重定向到一个文件:
user$ ( time ./foo ) > log.txt
标准输出:(空!)
标准错误:
stderr says hi
real 0m0.017s
user 0m0.003s
sys 0m0.004s
log.txt: 标准输出打招呼
组合 I/O,捕获 time 的输出,并将管道连接到 tee
如何做到这一点?我在想像下面这样的东西:
( time ./foo 2&>1 ) | tee log.txt
标准输出:(空!)
stdout says hi
stderr says hi
real 0m0.017s
user 0m0.003s
sys 0m0.004s
stderr:(空!)
log.txt:
stdout says hi
stderr says hi
real 0m0.017s
user 0m0.003s
sys 0m0.004s
执行以下工作,除非我 Ctrl-C (SIGINT) 过早退出程序。
( time ./foo ) 2&>1 | tee log.txt
当我也使用 Ctrl-C 时,我怎样才能让它工作?
【问题讨论】:
-
您的链接建议使用
(time ls) &> file,这也适用于您的情况。那么,为什么您忽略了&? (即(time ...) |& tee ...) -
@rici:好建议。使用
GNU bash version 3.2.57(1)-release(我无法在远程计算机上更新 BASH)时,该语法对我不起作用,尽管它确实似乎适用于GNU bash, version 4.4.19(1)-release(我可以并且已经更新了 BASH) .我会看看我的系统管理员是否可以在远程计算机上更新 BASH,但我仍然对解决方案感兴趣。 -
顺便说一句,管道到
tee的部分棘手之处在于 ctrl+c 向整个进程组发送了一个 SIGINT —— 所以它同时关闭了tee它会关闭运行time的子shell,这意味着您无法保证(即它取决于比赛的结果)tee是否真的能够刷新该shell 的输出。
标签: bash time pipe io-redirection tee