【问题标题】:Windows Batch - how to add timestamp while redirecting stdout to fileWindows Batch - 如何在将标准输出重定向到文件时添加时间戳
【发布时间】:2016-10-04 00:52:15
【问题描述】:

我在做make all -d --trace

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

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

那里有is a solution for Linux/Bash,但我在 Windows 上。

我创建了一个单行批处理文件 add_ts.bat : echo %time% %1

我尝试了以下方法,但只有一个时间戳(没有输出的行):

make all --trace -d 2>&1 | add_ts.bat

【问题讨论】:

    标签: c++ windows batch-file makefile gnu-make


    【解决方案1】:

    首先,您需要一个批处理文件,例如:

    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,方法是在其中使用重定向,这反过来意味着 你需要运行一个子shell来理解重定向,你需要 转义重定向操作符,这样它们就不会被顶层解释 贝壳。这一切都来了:

    @for /F "usebackq delims==" %%i in (`cmd /C %1 2^>^&1`) do @echo %time% %%i 
    

    以同样的方式运行。

    稍后

    我不明白为什么 |本身不足以将 STDOUT 和 STDERR 发送到 add_ts.bat 的 STDIN

    。我认为您是在两种误解的结合下工作的。

    :您认为程序的命令行参数与其标准相同 输入,或者它从其标准输入中获取命令行参数。它没有。 程序的命令行参数(如果有)作为固定列表传递给它 程序启动协议中的字符串。它的标准输入是一个输入流 操作系统同时可用,并默认连接到程序所在的控制台 开始。这个默认值可以在 shell 中被重定向操作符覆盖。该输入流的内容不是预先固定的。它会喂给 只要程序正在运行,无论何时输入到控制台或来自其重定向代理的程序,程序都会读取它。该程序 可以解析或忽略其命令行参数,并且完全独立于此,它可以读取或忽略其标准输入。

    您的程序add_ts.bat 是一个解析其第一个命令行参数的程序 - 它使用%1 - 并且不再理会。它完全忽略了它的标准输入。

    :您认为管道的效果,例如

    a | b
    

    是启动一个a 进程,然后,对于它写入标准输出的每一行,启动 一个独特的b 进程,它将自动接收a 写的一行 一个 single 命令行参数(不管一行中有多少单词)并做它的事情 使用那个单一的命令行参数。

    事实并非如此。操作系统启动一个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 redirection and piping 但它假设您知道程序必须做什么才能成为可流水线命令:成为上游命令, 它必须写出它的标准输出;要成为下游命令,它必须读取其标准输入。

    【讨论】:

    • 你能解释一下为什么我原来的球拍不起作用吗?我想这与 STDOUT 和 STDERR 缓冲有关
    • @Adrian 当批处理文件运行时,它将%1 替换为第一个命令行参数,依此类推,然后执行其逻辑并结束。将其输入管道化并不能让它用STDIN 的第一个完整 替换%1,然后为每个后续行重新运行。您的add_ts.bat 没有传递任何命令行参数,也没有用于读取其STDIN 的代码、管道或其他方式,因此它只打印了一次时间并停止了。
    • 我不明白为什么 | 本身不足以将 STDOUT 和 STDERR 发送到 add_ts.bat 的 STDIN。 ss64.com 是我了解如何/为什么的好地方吗?
    • @Adrian 请参阅答案中的进一步解释。
    • 我只是使用脚本为我的一个命令行应用程序的标准输出添加时间戳,该应用程序通常会运行数十分钟并具有恒定的标准输出,但重定向结果中的时间戳都是相同的,和我预想的不一样,是不是我误解了脚本的预期用途?
    【解决方案2】:

    如果您不介意额外的开销,那么使用批处理文件包装器是一个聪明的解决方案。否则我认为你必须修改 GNU make 才能让它打印出这些数据。

    如果由于某种原因这不合适,您可以使用 ElectricMake 获取该信息,这是一种兼容 GNU 的 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>
    

    这里,&lt;timing&gt; 标签显示了作业相对于构建开始的开始时间(0.291403 秒)和结束时间(0.296544 秒)。

    可以使用 ElectricMake 的配套工具 ElectricInsight 以图形方式查看和分析这些带注释的构建日志。

    ElectricAccelerator Huddle 是 ElectricAccelerator 的免费增值版本 - 在一定程度上完全免费使用,除此之外还有适度的即用即付费用

    免责声明:我是 ElectricAccelerator 的架构师。

    【讨论】:

    • emake 可以工作,但我的公司不想与之绑定,因为 ECloud 可能会决定随意将其设为非免费,甚至停止使用。我与您的销售代表交谈,他们说 免费 版本必须每 3 个月更新一次许可证。如果它因为蚕食您的企业销售而停产怎么办?你能谈谈这些担忧吗?
    • @Adrian ElectricAccelerator Huddle 是一个 freemium 产品,这意味着它既有免费的组件,也有提供额外功能的付费组件。
    • 我知道,但您仍然没有解释为什么“免费”版本会受到限制,即要求每 3 个月更新一次许可证。
    • @Adrian 你误会了。 Huddle 中的免费功能始终是免费的。也就是说,您可以永久免费使用 Huddle,使用最多四个本地代理运行可靠的并行构建。您还可以获得带注释的构建日志。该许可证管理付费功能,允许使用四个以上的本地代理以及来自其他主机的无限代理。从技术上讲,虽然 Huddle 处于测试阶段,但该扩展功能也是免费的,受 3 个月许可证的约束。过期后,您仍然可以使用始终免费的部分。
    • 我仍然不清楚 3 个月的期限适用于什么。只是“4核以上”的功能?
    猜你喜欢
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多