Каналы асинхронны в Windows cmd.exe. Они не ждут, пока завершится левая сторона, прежде чем передать информацию правой. Но ваша программа не демонстрирует этого по двум причинам.
1) Команда FOR /F не начинает итерацию строк до тех пор, пока не завершится выполнение команды в предложении IN(). Это справедливо для всех вариантов FOR/F. Весь результат предложения IN() буферизуется перед повторением любых строк.
Таким образом, ваш filter.bat не может продемонстрировать асинхронную природу каналов.
2) Команда MORE не будет записывать неполные строки — она ждет, пока не получит символ новой строки, прежде чем печатать на стандартный вывод. (если он не достигает конца файла).
Если вы действительно хотите увидеть асинхронную природу каналов, лучше использовать программу, которая считывает каждый символ из стандартного ввода и немедленно записывает его обратно в стандартный вывод.
Вот моя версия 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. Я рекомендую прочитать все ответы на Почему отложенное расширение не работает, когда внутри блока кода с конвейером? для хорошего обзора многих неинтуитивные вопросы.
person
dbenham
schedule
05.02.2014