Windows Batch - 如何在将标准输出重定向到文件时添加时间戳



我在做make all -d --trace

如何让 Gnu Make 输出它输出的每一行的时间戳?

更一般地说,如何为每个 STDOUT 和 STDERR 语句添加时间戳?

有一个针对Linux/Bash的解决方案,但我使用的是Windows。

我创建了一个单行批处理文件add_ts.batecho %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的架构师。

最新更新