1

I am trying to get a batch file to run a program and save the output with a prepended DateTime on each line to a log file, which needs to update in real time. We are restricted as we can only use cmd, powershell is not possible.

I have tried using:

 (for /f "delims=" %%i in ('ConsoleApp2.exe') do echo %DATE% %TIME% %%i >> log.txt)

but this only evaluates after the program has finished running and also gives all the output the same value.

I can't work out how to do this, can anyone please figure this out?

Edit:

Previously we used:

ConsoleApp2.exe >> log.txt

Which output to the log file as the program ran, however I couldn't work out how to get this to append the timestamp.

From comments (thank you Stephan):

setlocal enabledelayedexpansion
(for /f "delims=" %%i in ('ConsoleApp2.exe') do echo !TIME! %%i >> log.txt)

Fixes the issue of getting the timestamp to update correctly, however I still am unable to get an output in real time (while the program is running).

Edit: Lit's answer works however I really need a cmd (not being run in or running Powershell) only answer. An answer explaining how and why this is not possible would also be accepted.

Ben Gardner
  • 301
  • 3
  • 7
  • 1
    using [delayed expansion](https://stackoverflow.com/a/30284028/2152082) (`setlocal enabledelayedexpansion` and `... echo !date! !time! %%i ...` – Stephan Aug 16 '18 at 14:58
  • Hi Stephan, thank you, this does seem to answer one part of my question, however as far as I can tell this still only outputs anything to the log file after the program has finished running. – Ben Gardner Aug 16 '18 at 15:04
  • If the console application is writing output to STDOUT, the `FOR /F` will capture all the output. If the console application is writing directly to the console then the output cannot be captured. – Squashman Aug 16 '18 at 15:11
  • I need it to output to the file as the program runs as the program will run for a while. I believe it is outputing the STDOUT. I am assuming the FOR loop might not be the best way to do this, but it is the closest answer I have come up with. – Ben Gardner Aug 16 '18 at 15:17
  • 1
    Are you wanting to put a timestamp on every line of the output from `ConsoleApp2.exe`? – lit Aug 16 '18 at 16:37
  • The `FOR /F` command will by default read all values from the `IN` clause before it executes any of the `DO` commands. So you really can't do the real time time stamps the way you want. – Squashman Aug 16 '18 at 16:43
  • Hi Squashman, I am only using a for loop as it was the closest I could get. If there is another way of doing it that would work, that would make a great answer. I just need output from a program to have the date time prepended on each line and for it to run in real time rather than after the program has finished execution. – Ben Gardner Aug 17 '18 at 08:18
  • Hi Lit, yes, I am trying to prepend the timestamp to every line of the output from ConsoleApp2.exe, however this also needs to occur in real time rather than after the program has finished running, which is what my current example does. I have edited my question to hopefully make this clearer. – Ben Gardner Aug 17 '18 at 09:50
  • It's possible with pure batch. Like the answer of lit you could use a pipe, but not piping to powershell, instead to a batch file. The only problem is that it's tricky to read from a pipe with batch, but it can be done. You could search for tee.bat – jeb Aug 22 '18 at 13:14
  • You could modify this batch file for your problem [Dostips: tee.bat](https://www.dostips.com/forum/viewtopic.php?f=3&t=5386#p32615) – jeb Aug 27 '18 at 07:22

1 Answers1

0

Here is another way. Sorry about my previous answer. Everyone is correct that the cmd FOR loop will wait until everything is complete. Hopefully, this will not.

=== bat1.bat(ConsoleApp2.exe surrogate to produce some lines)

@ECHO OFF
FOR /L %%a IN (1,1,3) DO (
    ECHO line %%a
    ping -n 3 localhost 1>NUL 2>&1
)

=== logger.ps1

$Input | ForEach-Object { "$(Get-Date) $_" }

=== usage

CALL bat1.bat | powershell -NoProfile -File .\logger.ps1
lit
  • 14,456
  • 10
  • 65
  • 119
  • Hi Lit, I am afraid this wont work for us either as we need an entirely cmd based answer, as was in the question, powershell is not possible. – Ben Gardner Aug 20 '18 at 08:09