5

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).

Marc
  • 13,011
  • 11
  • 78
  • 98
  • Did you see this [answer](https://stackoverflow.com/questions/34522438/how-can-a-batch-file-read-piped-input-and-write-the-result-to-a-file)? And this [one](https://stackoverflow.com/questions/52575812/how-to-get-piped-input-in-windows-batch-file)? – Squashman Apr 15 '19 at 15:44
  • 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 Apr 15 '19 at 15:50
  • Yes, I've got that info @Squashman, there seems to be no way to access STDIN (CON is it not). – Marc Apr 15 '19 at 18:34
  • @Compo, I have added some back story. – Marc Apr 15 '19 at 18:34
  • *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 Apr 15 '19 at 19:04
  • *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).* is also wrong. Your concepts don't align with the real world. – Noodles Apr 15 '19 at 19:16
  • Thanks, your comments have helped me not a bit. – Marc Apr 15 '19 at 19:56
  • https://archive.org/stream/NTDocumentation/Windows_NT_Shell_Scripting_djvu.txt – Noodles Apr 15 '19 at 20:46
  • @Marc I guess I don't understand because the code in both links consume standard input. – Squashman Apr 16 '19 at 00:36
  • Neither of the links is able to capture STDIN (not console input) AFTER executing something else (say POWERSHELL). – Marc Apr 16 '19 at 07:59

1 Answers1

1

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 ""
MC ND
  • 69,615
  • 8
  • 84
  • 126
  • I definitely don't want to read from the console - I want the piped, stream of input. – Marc Apr 15 '19 at 19:57
  • @Marc, I'm not sure I'm understanding the problem. This code just shows that there is not any problem to retrieve the piped data after executing another code. Just ensure your "initial" commands don't consume the piped data by assigning a different input source. That way the piped data will be available for the "final" command that reads it. Is it not the problem to solve? – MC ND Apr 15 '19 at 21:54