Трубы асинхронные в Windows cmd.exe. Они не дожидаются завершения левой части перед передачей информации вправо. Но ваша программа не демонстрирует это по двум причинам.
1) Команда FOR/F не начинает повторять любые строки до тех пор, пока команда в предложении IN() не завершится. Это справедливо для всех вариантов FOR/F. Весь результат предложения IN() буферизуется до повторения любых строк.
Так что ваш filter.bat не может продемонстрировать асинхронный характер труб.
2) Команда MORE не будет писать частичные строки - она ждет, пока не получит символ новой строки перед печатью на стандартный вывод. (если он не достигнет конца файла).
Если вы хотите по-настоящему увидеть асинхронный характер труб, лучше использовать программу, которая считывает каждый символ из stdin и сразу же записывает его обратно в stdout.
Настоящая версия FEED.BAT - это несколько строк с несколькими паузами. Он также записывает три символа без перевода строки с паузой после каждого из них.
@echo off
echo something
timeout /nobreak 3 >nul
echo something else
timeout /nobreak 3 >nul
for /l %%N in (1 1 3) do (
<nul set /p "=%%N"
timeout /nobreak 3 >nul
)
echo(
echo Done
Вот моя версия FILTER.JS - она читает один символ из стандартного ввода и записывает их на стандартный вывод до тех пор, пока не достигнет конца файла.
while (!WScript.StdIn.AtEndOfStream) WScript.Stdout.Write(WScript.StdIn.Read(1));
А вот команда протестировать поведение
feed | cscript //nologo filter.js
А вот выход с <pause>
вставляется всякий раз, когда есть пауза перед тем большей производительности.
something
<pause>something else
1<pause>2<pause>3<pause>
Done
Мой выше тест показывает, что труба будет немедленно отправить любую информацию, которую он получает (при условии, фильтр готов получить его).
Конструкция фидера и/или фильтра может маскировать свободное протекание. У вашего оригинального теста было узкое место в фильтре, поскольку он ждал ввода всех данных перед продолжением. Также возможно, что фидер будет держать вещи вверх. Некоторые программы имеют буферизованный выход. Фидер может не отправлять данные до тех пор, пока буфер не будет заполнен, или буфер не будет сброшен, или поток не будет закрыт.
Существует ряд особенностей поведения, связанных с трубами Windows. Я рекомендую прочитать все ответы на Why does delayed expansion fail when inside a piped block of code? для хорошего обзора многих неинтуитивных проблем.
В какой версии Windows есть команда SLEEP? Я использую TIMEOUT (или PING hack) – dbenham
Это не имеет ничего общего с тем, как работает командный процессор, и все, что связано с самой программой. Который автоматически переключает вывод в буферный режим, делает трубопровод намного более эффективным. Основными функциями CRT являются _isatty() и setvbuf(). Но с новым поведением этот вывод не покидает буфер до тех пор, пока он не заполнит емкость. Или сама программа очищает буфер. Что не хватает в этой программе. Это очень удобно, если у вас есть источник программы. –