I've managed to write a non-blocking asynchronous batch implementation of tee that uses only internal batch commands plus the FINDSTR native external command.
It writes all output to a temporary file in the %TEMP% folder, and simultaneously reads from that same file using SET /P. The temp file name incorporates the current time to 0.1 seconds, and the script automatically loops back to try again if another process happens to grab the same temp name.
The use of SET /P results in the following limitations:
1) Line lengths are limited to 1021 bytes, minus the line number + colonn prefix that is temporarily added to each line.
2) Trailing control characters are stripped from each line.
batchTee.bat
Code: Select all
::batchTee.bat OutputFile [+]
::
:: Write each line of stdin to both stdout and outputFile.
:: The default behavior is to overwrite any existing outputFile.
:: If the 2nd argument is + then the content is appended to any existing
:: outputFile.
::
:: Lines are limited to ~1000 bytes, and trailing control characters will
:: be stripped from each line of output.
::
:: The exact maximum line length varies depending on the line number.
:: The SET /P command is limited to reading 1021 byte lines, and each line
:: is prefixed with the line number and a colon when it is read.
::
@echo off
if "%~1" equ ":tee" goto :tee
setlocal disableDelayedExpansion
:lock
set "teeTemp=%temp%\tee%time::=_%"
2>nul (
9>"%teeTemp%.lock" (
(findstr /n "^"&echo END) >"%teeTemp%.tmp" | <"%teeTemp%.tmp" "%~f0" :tee %*
(call )
) || goto :lock
)
del "%teeTemp%.lock" "%teeTemp%.tmp"
exit /b
:tee
setlocal enableDelayedExpansion
set "redirect=>"
if "%~3" equ "+" set "redirect=>>"
8%redirect% %2 (
for /l %%. in () do (
set "ln="
set /p "ln="
if defined ln (
if "!ln:~0,3!" equ "END" exit
set "ln=!ln:*:=!"
(echo(!ln!)
(echo(!ln!)>&8
)
)
)
Usage is as expected for a tee utility:
Code: Select all
dir | batchTee output.txt
Content can be appended to an existing file by adding + as a second argument:
Code: Select all
dir | batchTee output.txt +
Dave Benham