:: inputDemo2.cmd:: From the desk of Frank P. Westlake, 2011-09-21:::: Determines if there is redirected or piped input waiting and identifies:: which it is. This test conforms to the precedence of REDIRECTION over PIPE.:::: This test is not reliable because if file handle 3 is mishandled by any:: process in this console group then the handle can become lost or confused.:::: This test is not reliable because there are other command line:: configurations which will pass the test as a PIPE but which have no pipe.:::: Unfortunately this test prints a blank line in the console window:: if input is not REDIRECTION.@Echo OFFSetLocal EnableExtensions

:: This file catches the error report if input is REDIRECTION. It will be deleted.Set "TempFile=%TEMP%\inputTest"

:: INPUT either remains undefined or it is defined with either "REDIRECTION" or "PIPE".Set "INPUT="

:: BEGIN TEST.:: Print something redirected to the console window. This redirection fails if the:: input stream has been redirected from a file; an error report is sent to "%TempFile%".:: ERRORLEVEL does not receive the value of this error so the report is necessary.:: This redirection does not fail if it is done in FOR's execution chamber so it must be:: done here.Echo(>&3 2>"%TempFile%"

For %%f in ("%TempFile%") Do ( ERASE "%TempFile%" REM If file size is not 0 there was a redirection error so the input type is REDIRECTION. If "%%~zf" NEQ "0" ( Set "INPUT=REDIRECTION" ) Else ( REM "I'm_HERE"'s pipe test. Determine if a PIPE is indicated. Echo %CMDCMDLINE%|FINDSTR "\"/c\" %0">NUL: && Set "INPUT=PIPE" )):: Finished. Show the result.If DEFINED INPUT ( Echo Input type is %INPUT% REM Show the input. MORE) Else ( Echo No PIPE and no REDIRECTION.)

But my question still stands: I’m looking for a robust method to check for redirected input (ie, prog.cmd < file.txt).

The program in the OP correctly identifies redirected input from a file. But like FPW says in the comments, it’s fragile, requires a temporary file, and outputs a blank line to the console. Is there a more robust solution? Can the above code be improved upon?

And I’m aware of Aacini’s typeofhandle program, but it’s a .com file and they won’t work on 64-bit Windows. Anyways, my point is I’m looking for something as portable as possible. Any helpful suggestions gratefully appreciated.

The technique in the original post is very fragile, to the point I would never rely on it. The redirected input test only works if there has not been any other redirection prior to redirecting the input.

For example, the following falsely claims there is no redirected input or pipe:

Yesterday, I build a new solution to detect STDOUT redirection.
Currently, the detection for STDERR redirection is not working correct.
[strike]It produces a wrong result when the STDOUT redirection is active.[/strike]
Edit: I found a simple way for STDERR, 1>&2 needs to be present in the findstr statement.

The complete concepts is build on the tabulator/backspace technic of @Aacini Move cursor to *any position* using just ECHO command.
The trick is, that trying to move the cursor before the home position results into an error message, but there is no such message when the STDOUT/ERR is redirected

First off, I don't like any method that reads from stdin or writes to stdout or stderr because I view that as destructive - the result of a script can change from what it was without any detection.

But ignoring that concern...

"#1 No redirection", "#3 stderr redirected", and "#4 both redirected" all work for me.

But "#2 stdout redirected" does not work. The control codes, including the CLS formfeed, are all non-functional, causing a little box to be printed to the console for each control character. And the script lists both stdout and stderr as redirected. I've used * to represent each little box on my output screen

cmd will not be crashed by this, rather it will terminate itself in a controlled manner.

At first I thought stack overflow might be the cause of the termination, as it may repeatedly try to write to stderr but that will generate another error and this continues until the stack is full. Then I checked the behavior in debugger, and it turned out that cmd explicitly checks if it can write to stderr, and if it can not, it terminates itself immediately by calling CRT exit function.

From the batch programming perspective it doesn't make much difference how cmd is terminated, but it guarantees that the behavior is by design.

This can be used for example to detect if the right side of the pipe is terminated. As I used the technique in this SO Answer

(
for /L %%# in (0,0,1) do @(
echo doIt
timeout /t 1 /nobreak >nul
%= This guarantees we will not loop infinitely when the right side of pipe is closed =%
echo PingPipe 2>&1
)
) | MyCustomStreamConsumerApp