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

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.

Related

Redirecting output to file in batch file requires closing? (batch script)

In a batch script redirecting the output to a file like so
set "output=C:\output.txt"
echo Blah blah blah. >> %output%
Is it required that the file is closed after the redirection of writing stuff to it is completed (similar to the approach in other programming languages)?
I have tried searching for related information online but could not find something on it; I assume the fact that most scripts are closed after they finish their tasks (commands) is maybe the reason why.
But if say a script is to run in an endless loop where a different output file is written (e.g. by appending the time to the output file name) or if new output is constantly being redirected to the same output file, could the "not closing of the file" potentially lead to problems, memory or other?
No, you don't have to close any file handles in batch scripts. You don't know the file handle value so you could not even close it if you wanted to.
On Windows, all open kernel handles are closed when a process ends/crashes but since a batch file is interpreted by cmd.exe without starting a new cmd.exe process in most cases, it cannot take advantage of the automatic handle cleanup and will manually close the file handle after each redirected operation.

How do I automate an input answer in a batch file

So I have been working on a simple batch file, that thanks to #Magoo, I was able to solve the first question I had about it.
Now my next question,
Is there a way to automate an answer input.
Since I'm running Windows 7 (this is the current course I am on, in my quest to become a knowledgeable IT guy), I cannot use PowerShell to extract an image, and to my best knowledge, PowerISO is the only program I have found where I can use command lines in a batch file to extract the .iso file that I want, and place it on the drive/directory that I want. However, I came across the need to input an answer 'NoAll' before I could finish the extraction. I'm wondering if there is a way to automate that answer, if needed. It will only be used once, as the NoAll implies.
All the code is correct and the batch file works properly barring this one little hiccup.
Here's my batch file.
echo
cd "C:\Program Files\Windows AIK\Tools\PETools"
call copype amd64 "C:\winpe-amd64"
copy "C:\winpe-amd64\winpe.wim" "C:\winpe-amd64\iso\sources\boot.wim"
copy "C:\Program Files\Windows AIK\Tools\amd64\imagex.exe" "C:\winpe-amd64\iso" & cd "C:\Program Files\Windows AIK\Tools\amd64"
oscdimg.exe -n -bC:\winpe-amd64\etfsboot.com c:\winpe-amd64\iso c:\winpe-amd64\winpe-amd64.iso
cd 'C:\program files\powerISO"
piso extract "C:\winpe-amd64\winpe-amd64.iso" / -od f:
as the extract begins to run, I get a prompt for input, and this is where I would like to be able to automate the 'NoAll' answer.
Thanks in advance!
Since all you need to do it input text, you can simply echo what you want to type and then pipe it to the other command.
echo NoAll|piso extract "C:\winpe-amd64\winpe-amd64.iso" / -od f:
You can use the input file and input redirector '<' to automate most of input. For example, create a text file 'NoAll.txt' with the content "NoAll" (without quotes, and add a newline at the end for 'Enter' key). On the command that needs NoAll, execute it as follow:
piso extract "C:\winpe-amd64\winpe-amd64.iso" / -od f: < NoAll.txt

Is there a way to run a command line "inside" a symlink?

I have a symlink named example.avi that points to a real example.avi video file. When a program tries opens the symlink, it really opens the video file. But now I would like execute a command line whenever a program tries to open the symlink file.
Is that possible?
ps: windows
No, there is no built-in way of creating a symlink or other file system object that causes a command to be executed when it is opened by an application.
It should in principle be possible to do this with a file system filter driver. But that's very complicated. I believe there are some third-party tools to simplify this sort of task, but I don't have any experience with them.
While I am clearly ignorant on the subject of symlinks in Windows (see my comments on your question). I just played with it and proved that you could basically do this by symlinking to a wrapper for your avi. I.e. symlink to an exe or a batch file, etc. which does what you want and then opens the avi. Here's a test I ran with txt files and notepad:
Create a file called test.txt with some text. Create a file next to it called test.bat. Here's the batch:
notepad test.txt
When you run the batch, it just opens the txt in notepad.
Then I added a symlink:
mklink test2.txt test.bat
Now, when I type test2.txt in the command prompt, or double click on it, it runs the batch and opens the test.txt file. Obviously, you can use the same basic logic. It doesn't, however, fire the batch off when I open the symlink in Notepad++. It just opens to batch for editing instead.
Of course, maybe you don't want a second file, in which case you need to literally embed your avi in some wrapper. I guess we ned to know more about what you want to do. It sounds like an attempt at malware hidden in a video to me...

Build output from Visual Studio 2010 external tools in output window

I run a batch file as an external tool (by adding it in Tools->External tools) in VS2010 (I've checked the "Use Output Window" option). This batch file performs compilation as in VS command prompt. The project that I'm working on has makefiles for various folders, so I use the mk command to build.
In the batch file, I set up the VS environment and then run the following commands:
cd $directoryWhichContainsFileToBuild
mk
cd main //This directory contains the executable that is to be built
mk
I see the output of the first mk in the Output window but after that it just hangs. I also tried to use an echo after the first mk but even that doesn't get printed in the output window (the ones before it can be seen).
Somewhere I read that there is an issue with VS 2010 output window where it hangs after showing some output, although I couldn't really be sure that that is what's the issue here.
Do I need to enable some other VS setting? Has anybody else encountered this issue?
Thanks.
Update: I unchecked the "Use Output Window" and "Close on exit" option, and I see an extra statement: "Press any key to continue". On doing that however, their is no further processing of the batch file.
Update2: Got it to work by prefixing mk with "call".
Thanks all who tried.
It is always good in batch files to specify executables with full path and file extension instead of just the file name. This avoids often lots of problems.
Here was just mk used instead of mk.bat. Therefore on every compile the command line processor cmd.exe searches for mk.* and then checks if any of the found files have an extension listed in environment variable PATHEXT. The order of file extensions separated by a semicolon in PATHEXT defines the order of execution in case of a directory contains multiple mk.* files.
If a command being specified in a batch file not being an internal command of cmd.exe without path, command line processor searches first for a file with given name in current working directory. This is often one more cause of error. What is the current working directory on execution of the batch file?
Next if no file to execute can be found in current working directory, the command line processor searches in all folders being listed in environment variable PATH separated by semicolons.
So specifying in batch files edited only rarely an external application or another batch file with full path, file name and file extension, in double quotes if necessary because of 1 or more spaces in path or file name, helps command line processor to more quickly execute that application or batch file and avoids problems because of executable not found (unknown command).
Sure, when typing commands in a command prompt window, nobody wants to enter the executables with full path, name and extension. But for batch files it is always good to be not lazy and type files to be executed with full path and extension.
TripeHound has given already the explanation why the observed behavior occurred here.
If a batch file is executed from another batch file without using command call, the command line processor continues batch execution in the other batch file and does never come back. In a C/C++ program this is like using goto with the difference that parameters can be passed to the batch file containing the further commands to be executed next.
But running from within a batch file another batch file with call results in continuation of execution below the line calling the other batch file once the other batch file reaches end, except command exit is used in the called batch file without parameter /B.
So the solution here is using:
cd /D "Directory\Which\Contains\File\To\Build"
call "Path\Containing\Batch\File\To\Build\mk.bat"
rem With mk.bat not changing current working directory change working
rem directory to the directory containing the executable to be built.
cd main
call "Path\Containing\Batch\File\To\Build\mk.bat"
BTW: exit exits command processor, exit /B exits just current batch file. I'll give you three guesses why the parameter is B and not a different letter. Yes, B is the first letter of batch.
Writing as a separate answer instead of an update in the question itself as many readers see the header and skim to the answer: got it to work by prefixing mk with "call". (#TripleHound has also posted the conceptual reason for it in the comment above.)

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

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

Resources