Подтвердить что ты не робот

Есть ли способ перенаправить ONLY stderr на stdout (не объединить два), чтобы он мог быть передан в другие программы?

Я работаю в среде Windows CMD.EXE и хочу изменить вывод stdout в соответствии с stderr, чтобы я мог передавать сообщения об ошибках в другие программы без использования файла.

Я знаю нотацию 2>&1, но объединяет stdout и stderr в один поток.

То, что я думаю, будет примерно таким:

program.exe 2>&1 | find " "

Но это объединяет stdout и stderr так же, как:

program.exe | find " " 2>&1

Я понимаю, что могу сделать...

program 2>file
type file | find " "
del file

Но это не обладает гибкостью и мощью нотации program | find " ". Для этого требуется, чтобы program завершил свой вывод до того, как этот выход можно обработать.

4b9b3361

Ответ 1

Интересный вопрос: -)

CMD обрабатывает перенаправление слева направо. Вы хотите сначала перенаправить 2 (stderr) в & 1 (stdout), затем перенаправить 1 (stdout) на другое. На этом этапе stderr все равно будет перенаправлен на предыдущее определение stdout. Труба по-прежнему будет работать со старым определением stdout (который теперь содержит stderr).

Если вам не нравится stdout, вы можете перенаправить на nul

program.exe 2>&1 1>nul | find " "


Если вы хотите записать stdout в файл, переадресовываете его в файл

program.exe 2>&1 1>yourFile | find " "


Если вы все еще хотите видеть stdout на консоли, но вы хотите только передать stderr в FIND, вы можете перенаправить 1 на con:

program.exe 2>&1 1>con: | find " "

Обратите внимание, что существует тонкое различие между исходным определением stdout и con:. Например, cls >con: не очищает экран, вместо этого он печатает забавный символ.

Можно поменять stdout и stderr, если вы используете третий дескриптор файла (изначально неиспользуемого). 1 и 3 будет содержать исходное определение stderr, а 2 будет содержать исходное определение stdout.

program.exe 3>&2 2>&1 1>&3 | find " "

На самом деле существует дополнительный дескриптор файла, определенный каждый раз при перенаправлении. Исходное определение сохраняется в первом доступном неиспользуемом дескрипторе файла. Предположим, что до выдачи вышеуказанной команды не было перенаправления. 3>&2 не сохраняет исходное определение 3, потому что 3 ранее не определялось. Но 2>&1 сохраняет исходное определение stderr в 4 (3 уже использовалось), а 1>&2 сохраняет исходное определение stdout в 5.

Так технически, явное перенаправление 3 не требуется для замены stderr и stdout

program.exe 2>&1 1>&3 | find " "

2>&1 сохраняет stderr в 3 и 2, перенаправляется в & 1 (stdout). 1>&3 сохраняет stdout в 4 и 1 перенаправляется в & 3 (stderr).

Но приведенное выше будет работать только правильно, если вы уверены, что 3 еще не были определены до выдачи команды. Гораздо безопаснее явно определить 3, как в моем предыдущем примере кода.

См. Почему мой конец перенаправления stderr после завершения команды? И как это исправить? для некоторых действительно диких приключений с перенаправлением: -)

Ответ 2

От взгляда на http://support.microsoft.com/kb/110930 кажется, что вы хотите 2>&1 1>NUL. Для вас должно быть что-то вроде следующего:

test.exe 2>&1 1>NUL | find "someErrorString"