.bat script: redirect output to command line

Microsoft Windows xp professional w/serv...
May 18, 2010 at 02:44:36
Specs: Windows XP
I have created a .bat file which is running quite well. Thing is, now I would like to redirect the output to a logfile - that's not a big problem, but I would like to see the written log in parallel on the screen.
Can you tell me how to enable that in my script?
E.g. like in Unix: script.sh 2>&1 | tee log.txt

Here is my script (it's just an example):

@echo off

echo Before writing the log

echo Calling subroutine with log

(call :method) > log.txt | type log.txt

goto end

:method
echo this is a test
goto end

:end
exit /B 0

When I try to run it I get the following error:

Before writing the log
Calling subroutine with log
Ung├╝ltiger Versuch, ein Sprungziel au├čerhalb einer Batchdatei aufzurufen.

Do you have an idea?


See More: .bat script: redirect output to command line

Report •

#1
May 18, 2010 at 03:26:08
You can write every thing twice, redirecting one of the outputs to "con"


:method
echo this is a test
> con echo this is a test
goto end

Anything sent to "con" will be displayed, nothing can redirect it.


Report •

#2
May 18, 2010 at 03:44:07
You should also be able to get away with this:

@echo off
> log.txt call :test
> con type log.txt
goto :eof

:test
echo Yep this sort of works......
goto :eof


Report •

#3
May 18, 2010 at 04:08:32
Well, this is not exactly what I am looking for. I have 10 different scripts and each is running about 30 minutes, doing DB updates and stuff like that.
And I would like to see the output of the running script paralell to the time where the log is being written.
If I do it in the way as suggested I would get a log and finally the content of the log is shown - but when the script hangs up because of an DB issue I do not see that on the screen but have to look up in the log.
So, I would like to see the output on the command line as well as in the log, and that all in the same timeframe...

Any suggestions for that?


Report •

Related Solutions

#4
May 18, 2010 at 05:14:11
I found a solution - all I have to do is recalling the script:

if /i n%1 EQU n (
call test doNotRepeat > log.txt | type log.txt
exit /B %ERRORLEVEL%
)

echo Welcome to the script!

:end
exit /B 0


Report •

#5
May 18, 2010 at 07:02:51
That probably won't work; TYPE terminates as soon as it reaches the EOF.

Report •

#6
May 18, 2010 at 08:33:16
i don't know if this will help, or if you are willing to use vbscript:
'----- save as: tee.vbs
set xin=wscript.stdin
set cout=wscript.stdout
set xout=wscript.stderr
do while not xin.atendofstream
x=xin.readline
cout.writeline(x)
xout.writeline(x)
loop
'-------- end

usage: command | cscript //nologo tee.vbs 2>log


Report •

#7
May 18, 2010 at 08:38:11
That probably won't work as well; If you reach the end of the stream before the program terminates, .ReadLine (or .Read or .ReadAll) blocks until the program terminates.

set xout=wscript.stderr
If you're going with C++ names, it's cerr. If you're not, just ignore me.


Report •

#8
May 18, 2010 at 08:50:30
i think i know what you mean...
echo nn
causes an end-of-stream to occur?

then it would become messy with artificial "end of output" flag
generated by the generating script, like
do while x != "EOFEOF"

or do you mean it "blocks" as in buffering?
now i think about it, that's probably right.


Report •

#9
May 18, 2010 at 08:59:33
The latter. As in the script hangs until the program terminates.

EDIT: Your best bet would be to just get a tee like program for Win32.


Report •

#10
May 18, 2010 at 12:09:14
"If you're going with C++ names, it's cerr. If you're not, just ignore me."

@Razor:
as a matter of fact... now that you mention it, do you know
how to test for "end of stream" in C++? I thought I'd try out
the same setup using C++, but can't figure out how to
arrange the termination.


Report •

#11
May 19, 2010 at 05:57:54
nbrane: do you know how to test for "end of stream" in C++?
If you want to test cin for EoS, then it's unsupported, and any attempt to do so is undefined.

But since we're dealing with Win32, I'd start with PeekNamedPipe().


Report •

#12
May 19, 2010 at 12:50:14
thanks, I'll check, i remember seeing that. my C++ abilitily is
nil. I knew there were "tee"s already around, just wanted to "homebrew" one. ("have some homebrewed tee..." OH!)

Report •

#13
May 19, 2010 at 15:16:40
nbrane: just wanted to "homebrew" one
Well, that's easy enough to do. Especially if you don't care about error checking:
#define _WIN32_WINNT 0x0501
#include <cstring>
#include <iostream>
#include <fstream>

int main(int argc, char *argv[]) {
  if (argc < 2) {
    return 1;
  }

  char buff[4096] = {0};
  std::size_t len;
  std::cin.unsetf(std::ios_base::skipws);  
  std::ofstream fOut(argv[1]);
  if (!fOut)
    return 2;

  while (std::cin.get(buff, sizeof(buff), 0)) {
    len = strlen(buff);
    std::cout.write(buff, len);
    fOut.write(buff, len);
    fOut.flush();
  }
}


Report •

Ask Question