捕获通过管道传输到批处理文件的真实 STDIN

Mar*_*arc 5 stdin cmd batch-file

我想在执行其他命令从批处理文件中访问 STDIN 。我知道 .BAT 文件中的第一个命令接收 STDIN,但我想首先运行一些其他命令,然后捕获 STDIN。我还希望它能够与流式 STDIN 一起使用,即在开始时将 STDIN 捕获到文件中是不可接受的(请参阅下面的解决方法)。

现在,我知道这CON是代表 STDIN 的“文件”,它将TYPE CON输出(回显)STDIN。这似乎在批处理文件中根本不起作用。事实上,它似乎不代表 STDIN,而是代表用户/主机通过键盘输入的内容。

测试.bat

TYPE CON > output.txt
Run Code Online (Sandbox Code Playgroud)

测试运行:

C:>TYPE myfile.txt | test.bat
Run Code Online (Sandbox Code Playgroud)

预期结果:myfile.txt复制到output.txt.

实际结果:批处理等待用户输入(忽略通过管道传递给它的内容)并将键盘上键入的用户输入写入output.txt.

解决方法

作为解决方法:以下test.bat方法有效,但不支持流输入(例如来自tail命令):

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
Run Code Online (Sandbox Code Playgroud)

更新:背景故事: 我有一个简洁的 CMD,它使用 powershell 下载(通过 HTTP)任意 .ps1 脚本(就像包管理器一样)并即时执行它。如果我调用它,则会使用参数和REMEXEC.bat mymodule foo bar加载并执行。mymodule.ps1foobar

除了管道、流输入之外,这对于所有场景都非常有效。使用该findstr "^"作品用于管道输入,但不适用于开放流。使用 sayAWK /.*/作为 BAT 的第一行可以得到流输入,但只是将问题推到了后面。

最终我想要一个something.bat看起来像这样的(伪代码):

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

问题 22 是在downloadPSModule之前发生的executePSModule,因此无法访问 STDIN(为 BAT 第一行保留的特权)。

MC *_* ND 1

如果您需要从控制台检索输入或隔离从标准输入流的读取而不消耗管道数据,我会尝试直接从控制台读取类似的内容

@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 "" 
Run Code Online (Sandbox Code Playgroud)

执行时

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 ""
Run Code Online (Sandbox Code Playgroud)