Why can't I redirect stdout/err of a program run by a batch file, called by another batch? - windows

If I have this batch:
ScriptA.bat
someprog.exe
And this one:
ScriptB.bat
CALL ScriptA.bat
And I execute a command like:
ScriptB.bat > test.log
The output from someprog.exe is not logged. It flows through to the console. How can I avoid having to explicitly pipe the output of someprog.exe to a file, and instead just capture that from a higher level?
(Note I ultimately want to do this with a great many scripts launching assorted exes from inside those nesting, and I can't edit them all to redirect the output of each and every sub process they invoke).

I found the answer to this on another SO thread:
https://stackoverflow.com/a/11955380/3220983
As you'll see if reading the comments under the question, the problem I was encountering was that the messages I couldn't capture were not being piped to stdout or stderr at all! They were going straight to the console via something akin to a CON redirect from inside the specific executable I was trying to use.
The link I posted shows how to launch a PowerShell script from a batch script, which captures the entire console window contents, inclusive of CON output!

Related

Is it possible to obtain the _raw_/_unprocessed_ command line?

The windows API provides GetCommandLine() which returns the cooked command line used to start a process.
For instance, if a console application is started with the command:
MyProg.exe > OutputHere
The command line seen by MyProg.exe will not include the portion
> OutputHere
I'd like to somehow get the command line exactly as it was. Is this possible ? and if yes, how ?
Suggestions in C and/or plain (no objects) Delphi greatly appreciated. Creative solutions welcome (hopefully, not requiring ring 0 code.)
Thank you very much for your help.
NOTE: I can tell if the input/output, etc has been redirected but, that is not what I'm looking for. I need the original/uncooked command line.
The redirection or piping of stdin, stdout and stderr is handled the command interpreter, typically cmd.exe. The interpreter parses the command and creates the necessary files and pipes, and then creates the one or more processes needed to implement your command.
The processes that are created have no knowledge of the original command, they only get that part of the command that is not related to piping and redirection.
So what you are trying to do is not possible, at least within your process. The only thing that knows the original command is the command interpreter.
Whether or not you can retrieve the full command line including the pipe commands depends on whether your start the program in a command window or for example using the "Run" command from the Start menu. If you use the "Run" command from the Start menu GetCommandLine actually retrieves the full command line including the redirection commands, but redirection does not work as it seems to be a feature of CMD.EXE.
As others have pointed out, what are you trying to achieve here / why do you need to capture the redirection commands?

Redirecting cmd stdout and stderr back to parent

If I create a process from a cmd prompt using the start command (opening a new cmd) is it possible to redirect the stdout and stderr from that process back to the calling cmd?
If you want the output of the STARTed process to appear in the parent command console, then simply use the START /B option.
If you want to process the output of your command, then you should use FOR /F ... in ('someCommand') DO ... instead.
OK. I have yet to find a straightforward answer to this question. I didn't want to bog down my question with what I thought unnecessary detail but seeing as I'm being criticized for the lack of this I'll expand a bit here.
I want to automate the updating of FWs on our production line, so I've a python app that gets the FWs from ftp and then uses the processors flash tool via python subprocess command to upload it to the board's flash. OK for all but one of the tools.
The one tool seems to have a problem when it's not running in its own terminal, so I provide a start to the subprocess command string which allows it to run OK in its own terminal. However, I need the output from this other terminal for logging reasons.
A possible solution was to log stdout and stderr to file using >> or wintee and then poll this file via a thread in my original app (perhaps a rather convoluted solution to the question). However the tool also has a separate problem where it doesn't like any std redirection, so this doesn't work for me.

Hopw to stop the window from exiting during silent installation using batch file?

I wrote a batch file which does silent installation which is working fine. But how do I read the error messages if any appear? Can I write all the error/success messages to a log file? Also is there any command to stop the window from exiting?
There's the PAUSE command, which does nothing else then printing a message (Press any key to continue . . .) and waiting till a key is pressed. That would allow you to read any messages before the window goes. Just add the command to the batch file before the end of the script and/or at other position where you need it.
You could also try redirecting messages to a file. Typically console messages are redirected by adding >filename or 1>filename to the command line.
However, that would only redirect stdout messages, while there might also be stderr ones. Particularly, error messages are often printed to stderr, although that is not a rule and third-party programs may not follow that convention. Anyway, stderr messages would need to be redirected with 2>filename put on the command line.
To redirect both and make sure they go to the same file, use 1>filename 2>&1 on the command line.
You can add the redirection either to specific commands in the script or to the batch file in general. If you redirect specific commands of which there's more than one and you want the results to be logged in the same file, you'll need to use >> instead of > on all or at least all but the first command. That's because > would rewrite the output file if it existed and >> would append to it.

directing output from executed process to current cmd

Can I execute a program from a JScript script in such a way that the out put of the executed program will be written to the current console?
Currently I am using Shell.Application.ShellExecute and it is opening another new console for the executed application.
The JScript in my case is a wrapper around a compiler which is executed with the ShellExecute. So what happens is that all the compiler errors are lost because they are printed in another console.
If all you are worried about is capturing your compiler output then you can redirect the output to a file (I suggest both stdout and stderr). Something like this:
var shell = new ActiveXObject("WScript.Shell");
shell.Exec('YourCommand 1>yourOutput.txt 2>&1 ')
If you really want to see the ouptut in your current console window (I don't blame you), then you can use this:
var shell = new ActiveXObject("WScript.Shell");
WScript.StdOut.Write( shell.Exec('YourCommand 2>&1').StdOut.ReadAll() );
Note - if your command has the potential for asking for input, then you must provide input via a pipe or redirection in the command string (or you could redirect input to nul). Otherwise the program will hang.

Is there any way to redirect stderr output from a command run with “start” in the Windows command line?

I have a program that I want to automate runs for, since it takes awhile to complete. For some reason it outputs everything to stderr instead of stdout, and I'd like to check on its progress, so I find myself needing to redirect stderr output within a start command.
I tried this:
start "My_Program" "C:\Users\Me\my_program.exe" --some --presets --for --my_program.exe --output "C:\Users\Me\output_file_for_my_program" "C:\Users\Me\input_file_for_my_program" 2>"C:\Users\Me\my_program_output.log"
But it turns out that the redirect is being picked up by start, so that I get a 0-byte file with the result of "start" - namely, nothing. Is there any way to make the output redirection attach in some way to the output of my_program?
I've experimented with escaping, and neither "^2>" nor "2^>" seem to work.
If "Workaround Oriented Programmming" is acceptable (it probably is, you are programming Windows Batch lol), you could put the problematic code line in another .BAT file, without any "start" and then "start" this other BAT.

Resources