Захват истинного STDIN по трубопроводу в командный файл - PullRequest
1 голос
/ 15 апреля 2019

Я хочу получить доступ к STDIN из командного файла после некоторых других команд. Я знаю, что первая команда в файле .BAT получает STDIN, но я хочу сначала выполнить некоторые другие команды , а затем перехватить STDIN. Я также хочу, чтобы это работало с потоковым STDIN, т. Е. Недопустимо захватывать STDIN в файл при запуске с (см. Обходной путь ниже).

Теперь я понимаю, что CON - это "файл", представляющий STDIN, и что TYPE CON будет выводить (эхо) STDIN. Кажется, это не работает вообще внутри командного файла. Действительно, похоже, что он представляет не STDIN, а ввод пользователя / хоста с клавиатуры.

test.bat

TYPE CON > output.txt

Тестовый прогон:

C:>TYPE myfile.txt | test.bat

Ожидаемый результат: 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

ОБНОВЛЕНИЕ: Назад История: У меня есть аккуратный CMD, который использует powershell для загрузки (через HTTP) произвольного сценария .ps1 (как это сделал бы менеджер пакетов) и запуска его на лету. Если я вызываю REMEXEC.bat mymodule foo bar, он загружает и выполняет mymodule.ps1 с параметрами foo и bar.

Это прекрасно работает для каждого сценария, кроме потокового ввода. Использование findstr "^" работает для конвейерного ввода, но не для открытого потока. Использование скажем AWK /.*/ в качестве первой строки моего BAT дает мне этот поток ввода, но просто подталкивает проблему в будущем.

В конечном итоге я хочу something.bat, который выглядит следующим образом (псевдокод):

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

Подвох 22 в том, что downloadPSModule происходит ДО executePSModule и поэтому не имеет доступа к STDIN (привилегия, зарезервированная для первой строки BAT).

1 Ответ

0 голосов
/ 15 апреля 2019

Если вам нужно извлечь ввод из консоли или изолировать чтение из потока stdin, чтобы не использовать данные по трубопроводу, я бы попробовал напрямую читать из консоли что-то вроде

@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 "" 

При исполнении

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 ""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...