How to capture and display output from a task via Windows CMD - windows

I've got a PHP script which I'm running from a command line (windows) that performs a variety of tasks, and the only output it gives is via 'print' statements which output direct to screen.
What I want to do is capture this to a log file as well.
I know I can do:
php-cli script.php > log.txt
But the problem with this approach is that all the output is written to the log file, but I can't see how things are running in the mean time (so I can stop the process if anything dodgy is happening).
Just to pre-empt other possible questions, I can't change all the print's to a log statement as there are far too many of them and I'd rather not change anything in the code lest I be blamed for something going fubar. Plus there's the lack of time aspect as well. I also have to run this on a windows machine.
Thanks in advance :)
Edit: Thanks for the answers guys, in the end I went with the browser method because that was the easiest and quickest to set up, although I am convinced there is an actual answer to this problem somewhere.

You can create a powershell script that runs the command, reads the data from the command's STDOUT then outputs the output to both the log file and the terminal for you to watch. You can use the commands Write-Output and Write-Host.
Microsoft's site: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/tee-object.mspx
Another option would be use find a tee program that will read input and divert it to two different outputs. I believe I have seen these for windows but I don't think they are standard.
Wikipedia: http://en.wikipedia.org/wiki/Tee_(command)

I have always opened the log file up in my web browser. This allows me to refresh it easily and does not interrupt any writing to the file that windows does. It isn't particularly elegant but it does work!

You want the "tee" command for Windows. See http://en.wikipedia.org/wiki/Tee_(command)
Powershell includes a tee command, and there are also numerous versions of tee for Windows available, for instance:
http://unxutils.sourceforge.net/
http://www.chipstips.com/?p=129
Also can be implemented in VBScript if you prefer.
EDIT: Just occurred to me I should also mention the tail command: http://en.wikipedia.org/wiki/Tail_(Unix). Tail allows you to read the last N lines of a file, and also includes a "file monitor" mode that just continually displays the end of the file in real-time. This is perfect for log file monitoring since it allows you to watch the log in real-time without interfering with the process that's writing to the log. There are several implementations of tail for Windows, both command line and GUI based. Microsoft's Services For UNIX packages (or whatever they're calling it now) also include a version of tail. Some examples:
mTail
Tail for Win32
WinTail
MakeLogic Tail
Some of these go far beyond just displaying the file in real-time as it updates and can send email alerts and colorize string matches, monitor multiple files at once, etc.

Slow:
for /f "delims=" %a in ('php-cli script.php') do #echo %a&echo %a>>log.txt
or in a batch file:
for /f "delims=" %%a in ('php-cli script.php') do #echo %%a&echo %%a>>log.txt

Related

How to work around ebook-convert.exe (in calibre portable) halting batch file execution?

I use ebook-convert.exe from a batch file, and on one of my machines (old Windows vista laptop), any calls ebook-convert.exe prevent further commands in a batch file from running (in that .bat file, or in that cmd shell instance for instance). The conversion to .mobi actually succeeds, prints no errors even in -v -v full verbose mode. I tried versions 1.20.0 and 0.9.6 of calibre portable. It seems to be related to the executable itself, and not to the specific conversion job (just running it with -h flag has same effect). I tried running cmd in administrator mode, wrapping it with 'call' command, nothing helps. Assuming the calibre issue is a black hole that can't be solved, is there a DOS trick I could possibly try to keep batch commands running no matter what odd thing happens with ebook-convert.exe on that machine?
Using call in a batch file should work on normal console programs but it is possible for programs to "escape" if they really want to.
Using Start instead might work but it does not wait by default and its syntax is not sane:
Start /B /WAIT c:\path\without\spaces.exe optionalParameter
or
Start "" /B /WAIT "c:\path\w i t h\spaces.exe" optionalParameter
Remove /B to run the application in a new console.
Another option is to call ping localhost and For (to get the file size with %%~zA) in a loop until the size of the destination file stops increasing. This is a bit of a hack and might not work, it depends on how the converter opens the file and how often it flushes the writes.

How can I run FIO for windows and redirect output to file and console simultaneously

I’m running FIO 2.1.8 (Windows 2012 R2) and I am trying to figure out how I can use a bat file with FIO and the –output= command, but also display the output to the console screen at the same time.
I want to be able to monitor the screen in real time but also need a log so I can parse for errors and metrics after the workload is done. The problem is it seems there is no way to do both.
If I include the output argument then all screen output is suppressed, and if I try to do any other type of redirection then the console never updates.
Does anyone know how to achieve this with FIO in Windows?
I've tried using
TEE (via Gow)
Standard dos redirection (eg &>1 )
Wrapping the bat file in a powershell script using START-TRANSCRIPT
In all cases this does not work.
"C:\Program Files\fio\fio.exe" --name=warmup --readwrite=randrw --rwmixread=70 --bs=64k --ba=64k --filename=E\:\FIO_
datafile.dat --size=32m --ioengine=windowsaio --runtime=900 --time_based --iodepth=4 --numjobs=32 --eta=always
Thanks...
PowerShell's Tee-Object worked for me:
& ./fio --eta=always --ioengine=null --thread --time_based --runtime=10s --size=1M --name=go | Tee-Object fioout.txt
(An aside: due to the way Windows works you don't exactly have pseudo-ttys so it's often hard for other programs to pretend to be terminals in a way the originating program won't detect as being a redirection to a file)

How do I Pipe Standard Error to a File in DOS (Batch File)?

How do I pipe standard error to a file in a DOS batch file? Piping using >> only pipes the standard output and the standard error still goes to the console.
Details of my issue:
I am running WinRAR via command line, in an automated daily backup. And the following example pipes WinRar's output, but not the error output which is what I want most, to winraroutput.txt:
RAR.exe a -esh -r "E:\backup.rar" "D:\*.*" >> winraroutput.txt
The issue is sometimes files are in use and when they are I want to know they were missed in the archive and record this in a .txt file next to each .rar file in case we ever have to go back. The missing files are easily replaced by reinstalling programs so it's no big deal to replace them, as long as we know they are missing. So it's just information that would be great to know, not necessary, in the time of need.
How do I output just the standard error output to the .txt file and, if possible but not necessary, leave the the regular output to the console?
Bonus points:
Bonus points if you can tell me how to delete the file if it's blank (no errors)! Asked here: How do I Detect (and Delete) a File if it is Empty using a Windows Batch File?.
Try this:
command.exe 2>file.txt
Or if you prefer not to see any errors, send it to nul:
command.exe 2>nul
This should leave std::cout on the console.

Self Updating Exe par on Windows

I am trying to create a script that will "self update" when it detects a new version on a server. Initially the idea I had was, when a new version is detected, download the file, then starts a DOS batch file that simply overwrites the original exe with the new one. I thought, that I could use sytem(start update.bat ) then immediately exit 0; The .bat file waits for a couple seconds, and then tries to delete the old exe. This fails, I guess because even when using system(start ... ), the new "process" is actually the same process, is this correct? Is there any way to launch a completely new process from perl in windows, that would allow me to delete the .exe? Or is there a different approach that would be better?
Thanks,
Eric Seifert
See the documentation on the Windows Restart Manager, an API introduced with Windows Vista that manages restarting applications, for updates, for you.
Ever heard of java WebStart? There is a PAR equivalent, PAR::WebStart
Basically, you configure it, then download code live from a trusted website
so your .exe would just be a frontend to PAR::WebStart, with the real program downloaded off your website
I know this is an old question, but I thought I'd put my solution here since I'm working on the same sort of thing. Your batch idea is the way I went, but the small change I made was to use exec() instead of system() since the former (according to this) "...executes a system command and never returns", which seems to release the running process. This appears to work both when running interpreted Perl files with Strawberry Perl, and when running compiled programs with PAR::Packer.
I've created test.pl, which was ultimately compiled to test.exe, as follows:
#!/usr/bin/perl
use 5.10.0;
use strict;
use warnings;
my $batch_file = <<"BATCH";
rem ### IT IS SAFE TO DELETE THIS FILE ###
\#echo off
ping 127.0.0.1 -n 2 -w 1000 > nul
echo Copying over update file...
copy testfile.exe test.exe
BATCH
open my $fh, '>', 'update.bat';
print $fh $batch_file;
close $fh;
exec( 'update.bat' );
testfile.exe is a standby "upgraded" version of test.exe, just to make sure that I can overwrite test.exe while it's running, and I can. The ping is a way to pause for 2 seconds to make sure the process has had a chance to exit before trying to overwrite the file.
Oddly enough, the created batch file update.bat can't delete itself, even though batch files can normally delete themselves. If I create a batch file with this:
start /b "" cmd /c del %0
It will delete itself without any errors. But if I include that snippet in update.bat, it complains that The process cannot access the file because it is being used by another process. I'm not sure why. Since this isn't particularly important in my application, I haven't pursued this. I just leave update.bat behind and let it be overwritten next time an update occurs. But I do notate in the file that it's safe to delete in case anyone looks at it later.

command line tool text output

I have a small command line tool and after running it, I'd like to display the text output in a way that's easy for someone to copy/paste and save it or email it to someone else.
Copy/pasting from a command prompt is not done in the standard way, so I don't want people to have to copy/paste from there. Saving the file to disk is possible, but the folder where the tool is located may not have access rights so the user would have to configure the output file location (this may be too tricky for some users).
I was thinking of launching notepad with some text in it, generated from the command line tool. Is this possible? Any other suggestions?
You can use clip.
After you have clip, which can be downloaded from the link above, you use the pipe (|) command to copy the previously executed command's output to the clipboard.
The article gives you the full explanation, but here are the basics with examples:
dir /h | clip – Copy the help manual for DIR command to the clipboard
tracert www.labnol.org | clip – Trace the path from your computer to another website – the output is automatically copied to the clipboard and not displayed on the screen.
netstat | clip - Check if your computer is connecting to websites without your knowledge.
I think your command sould receive the destination e-mail as a parameter and then after executing, your command you can have simple script/.BAT file which e-mails your text output to the user using the standard Telnet SMTP commands, like explained for example in the following page:
"http://www.yuki-onna.co.uk/email/smtp.html".
You could add an option to your program that tells it to copy its own output to the clipboard using the clipboard API. Then the user could just paste it.
I like the clip suggestion, though.

Resources