4
votes

I want to access STDIN from inside a batch file after some other commands. I know that the first command in a .BAT file receives STDIN but I want to first run some other commands and then capture STDIN. I also want this to work with streamed STDIN i.e. it is not acceptable to capture STDIN to a file at the start with (see workaround below).

Now, I understand that CON is the "file" representing STDIN and that TYPE CON would output (echo) STDIN. This does not seem to work at all inside a batch file. Indeed, it appears not to represent STDIN but user/host input by keyboard.

test.bat

TYPE CON > output.txt

Test run:

C:>TYPE myfile.txt | test.bat

Expected result: myfile.txt is copied into output.txt.

Actual result: The batch waits for user input (ignores what is piped to it) and writes user input typed on the keyboard to output.txt.

Workaround

As a workaround: the following test.bat works but does not support streamed input (e.g. from a tail command):

findstr "^" STDIN.txt
:: I can now run some other commands
:: And finally access my STDIN via STDIN.txt
TYPE STDIN.txt | AWK /e/ > output.txt

UPDATE: Back Story: I have a neat CMD which uses powershell to download (via HTTP) an arbitrary .ps1 script (like a package manager would) and execute it on the fly. If I call REMEXEC.bat mymodule foo bar it loads and executes mymodule.ps1 with the parameters foo and bar.

This works wonderfully for every scenario except piped, streamed input. Using the findstr "^" works for piped input but not for an open stream. Using say AWK /.*/ as the first line of my BAT gets me that streamed input but just pushes the problem down the road.

Ultimately I want a something.bat which looks like this (pseudocode):

downloadPSModule( "http://myrepo.com/modules/%1.ps1" )
STDIN | executePSModule %2 %3 %4

The catch 22 is that downloadPSModule happens BEFORE executePSModule and thus has no access to STDIN (a privelege reserved for the first line of a BAT).

1
Did you see this answer? And this one? - Squashman
I think it would be easier for us to assist you if you were to provide the specific task, with the actual executables, commands and code. - Compo
Yes, I've got that info @Squashman, there seems to be no way to access STDIN (CON is it not). - Marc
@Compo, I have added some back story. - Marc
Actual result: The batch waits for user input (ignores what is piped to it) and writes user input typed on the keyboard to output.txt. Yep that is right and you are telling to take what you type and put it in a file. Press Ctrl + Z to tell it when you have finished typing your file. - Noodles

1 Answers

0
votes

If you need to retrieve input from console or isolate reading from the stdin stream to not consume piped data, I would try directly reading from console with something like

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Part that reads from console, not piped input
    < con (
        set "data="
        set /p "data=Type something: "
    )

    echo(
    echo You have typed: [%data%]
    echo(

    rem Part that reads piped input
    find /v "" 

When executed

W:\>type test.cmd | test.cmd
Type something: this is a test

You have typed: [this is a test]

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Part that reads from console, not piped input
    < con (
        set "data="
        set /p "data=Type something: "
    )

    echo(
    echo You have typed: [%data%]
    echo(

    rem Part that reads piped input
    find /v ""