我在做make all -d --trace
如何让 Gnu Make 输出它输出的每一行的时间戳?
更一般地说,如何为每个 STDOUT 和 STDERR 语句添加时间戳?
有一个针对Linux/Bash的解决方案,但我使用的是Windows。
我创建了一个单行批处理文件add_ts.bat
:echo %time% %1
我尝试了以下内容,但我只有一个时间戳(没有输出的行):
make all --trace -d 2>&1 | add_ts.bat
对于第一个近似值,您需要一个批处理文件,如下所示:
add_ts.bat
@for /F "usebackq delims==" %%i in (`%1`) do @echo %time% %%i
你会像这样运行:
add_ts.bat "make all -d --trace" > buildlog.txt
但是,如果您想捕获和 时间戳STDERR
以及作为传递的命令的STDOUT
%1
,因为%1
周围的反引号运算符只会捕获STDOUT
要解决此问题,您需要在反引号中捕获 STDERR 和 STDOUT,方法是在其中使用重定向,这反过来意味着 您需要运行子外壳来了解重定向,并且您需要 转义重定向运算符,以便它们不会被顶级解释 壳。这一切都是:
@for /F "usebackq delims==" %%i in (`cmd /C %1 2^>^&1`) do @echo %time% %%i
以同样的方式运行。
后
我不明白的是为什么 | 本身不足以将 STDOUT 和 STDERR 发送到 STDIN 的add_ts.bat
是的。我认为你在两种误解的结合下工作。
一:你认为程序的命令行参数与其标准相同 输入,或者它从其标准输入中获取命令行参数。其实不然。 程序的命令行参数(如果有)作为固定列表传递给它 程序启动协议中的字符串。它的标准输入是输入流操作系统同时可用,默认情况下连接到程序所在的控制台 开始。重定向运算符可以在 shell 中覆盖此默认值。该输入流的内容不是预先固定的。它将馈送到 程序输入到控制台或从其重定向的代理输入,只要程序正在运行,当程序读取它时。该计划 可以解析或忽略其命令行参数,并且完全独立于此,它可以读取或忽略其标准输入。
您的程序add_ts.bat
是解析其第一个命令行参数的程序 - 它使用%1
- 并忽略更多。它完全忽略了其标准输入。
二:你认为管道的效果,例如
a | b
是启动一个a
进程,然后,对于它写入标准输出的每一行,启动 一个独特的b
过程,它将自动接收由a
编写的一行单个命令行参数(无论行中有多少单词)并完成其工作 使用单个命令行参数。
事实并非如此。操作系统启动一个a
进程和一个b
进程,并连接 一个a
过程的标准输出到一个b
过程的标准输入。对于 管道要工作,b
必须是一个读取其标准输入的程序。你add_ts.bat
不是这样的程序。它只是一个解析其第一个命令行的程序 参数:|
没有给它任何,命令行:
make all --trace -d 2>&1 | add_ts.bat
也没有给它任何东西。命令行:
make all --trace -d 2>&1 | add_ts.bat "Hello World"
会给它一个命令行参数,并且:
make all --trace -d 2>&1 | add_ts.bat Hello World
会给它两个,而不是一个,命令行参数,第二个被忽略。但无论如何 它不读取其标准输入,因此管道到它是徒劳的。
网站 ss64.com 在CMD
重定向和管道方面非常好 但它假设你知道一个程序必须做什么才能成为一个可流水线的命令:要成为一个上游命令, 它必须写入其标准输出;要成为下游命令,它必须读取其标准输入。
如果您不介意额外的开销,使用批处理文件包装器是一个聪明的解决方案。 否则,我认为你将不得不修改GNU使自己打印出这些数据。
如果由于某种原因这不可接受,你可以通过使用ElectricMake来获取该信息,这是一个与 GNU-make 兼容的 make 实现,其中包括许多增强功能,包括带注释的构建日志,这些日志具有构建中每个作业的微秒分辨率时间戳。 ElectricMake是ElectricAccelerator Huddle的一部分。
以下是对一个微不足道的"echo Hello World!"作业的一些注释:
<job id="J00007fb820002000" thread="7fb82f7fe700" start="3" end="4" type="rule" name="all" file="
Makefile" line="1">
<command line="2">
<argv>echo Hello, world!</argv>
<output src="prog">Hello, world!
</output>
</command>
<commitTimes start="0.291693" wait="0.296587" commit="0.296628" write="0.296680"/>
<timing invoked="0.291403" completed="0.296544" node="ecdroid3a-59"/>
</job>
在这里,<timing>
标记显示作业相对于构建开始的开始时间(0.291403 秒)和结束时间(0.296544 秒)。
这些带注释的构建日志可以使用ElectricInsight(ElectricMake的配套工具)以图形方式查看和分析。
ElectricAcceleratorHuddle是ElectricAccelerator的免费增值版本 - 在一定程度上使用是完全免费的,除此之外还有适度的现收现付费用
。免责声明:我是ElectricAccelerator的架构师。