Вот тестовый скрипт, который воспроизводит проблему, с которой вы столкнулись.
@echo off
2>nul 3>nul (
echo I want to see stream1
1>&2 echo I don't want to see this stream2
1>&3 echo I don't want to see this stream3
)
echo stream1 works fine
1>&2 echo stream2 is now "permanently" void. I don't see this.
1>&3 echo stream3 works fine
А вот вывод
I want to see stream1
stream1 works fine
stream3 works fine
stderr (поток 2) отключен "навсегда", даже для родительской оболочки CMD.EXE.
Вы можете избежать «постоянного» аспекта, осуществляя поэтапное перенаправление:
@echo off
2>nul (
3>nul (
echo I want to see stream1
1>&2 echo I don't want to see this stream2
1>&3 echo I don't want to see this stream3
)
)
echo stream1 works fine
1>&2 echo stream2 works fine
1>&3 echo stream3 works fine
И вот требуемый вывод:
I want to see stream1
stream1 works fine
stream2 works fine
stream3 works fine
Я не очень понимаю, что происходит.Но я провел несколько интересных экспериментов.Проверьте эту тему: http://www.dostips.com/forum/viewtopic.php?f=3&t=2836&start=30
Приложение
Как Эрберт обнаружил и поделился в своем комментарии, исправить это будет еще проще, если выпросто переключите порядок перенаправления - не нужно ставить его.
@echo off
3>nul 2>nul (
echo I want to see stream1
1>&2 echo I don't want to see this stream2
1>&3 echo I don't want to see this stream3
)
echo stream1 works fine
1>&2 echo stream2 works fine
1>&3 echo stream3 works fine
Обновление 2012-04-03 Мне кажется, я наконец-то понял механику WindowsCMD.EXE перенаправление.У меня есть рабочая теория, которая полностью учитывает все странное поведение, включая то, почему изменение порядка предотвращает «постоянное» перенаправление.Это также объясняет наблюдение Aacini о том, что дескриптор 3, по-видимому, связан с CON: (Это не так, он фактически не определен согласно документации Windows).
Ключевые моменты:
1 -Всякий раз, когда дескриптор (поток) перенаправляется, исходное определение переносится в первый доступный неопределенный дескриптор.Последовательные перенаправления всегда выполняются слева направо.
2 - Когда перенаправление заканчивается, исходные определения обычно восстанавливаются.Но если существует цепь перенаправлений, то восстановление выполняется только на 1 уровень.Это источник «перманентного» перенаправления.
Редактировать 2014-12-19: Другими словами, восстановление, похоже, выполняется с использованием структуры очереди (FIFO - First In FirstOut), когда он должен был быть реализован как стек (LIFO - Last In First Out).
3 - Когда CMD.EXE выполняет перенаправление, сначала сохраняет текущее определение в неопределенном дескрипторе, затемон перенаправляет первую ручку.Если первый дескриптор перенаправлен на первоначально неопределенный дескриптор, то он фактически перенаправляется на свое первоначальное определение!Вот почему echo hello 1>&3
выводит на консоль.
Полная теория и тестовые примеры доступны в двух последовательных постах на http://www.dostips.com/forum/viewtopic.php?p=14612#p14612.