Перенаправление вывода cmd Windows на стандартный ввод (>&0)

С вопрос на Stackoverflow я тестирую перенаправление из / в поток stdin. И эти тесты, пытаясь отправить данные в поток stdin, чтобы посмотреть, что произойдет, заканчиваются хаотичным поведением.

команды типа

echo testing >&0
dir >&0 
cls >&0

создает System can not write to the specified device (кажется, stdin-поток только для чтения, может быть), но такие вещи, как

  • vol >&0 не показывать ошибка

  • set /p "var=prompt" >&0 ждет ввода, не показывая приглашение и не показывая никакой ошибки

  • pause >&0 буду ждать без каких-либо ошибок, но при нажатии ошибка

и последней каплей является перенаправление stderr. При использовании внутренних команд, отправляющих вывод в stderr, он перенаправляется в stdin, например

call "noFile" 2>&0
dir  "|" 2>&0

результат-cmd.exe будет закрыто. Но не всегда. Такие вещи, как

dir "|" * 2>&0
dir * "|" 2>&0

работайте без проблем, скрывая текст, отправленный в stderr, и печатая остальную информацию.

Итак, вопрос в том, является ли это ошибкой, документирована ли она где-то, и я не могу ее найти, или это ожидаемое поведение, и есть что-то очевидное, что мне не хватает?

8
задан Community
11.03.2023 1:31 Количество просмотров материала 3630
Распечатать страницу

3 ответа

учитывая, что CMD.EXE печально недокументирован, я не уверен, каким должно быть ожидаемое поведение. Я, конечно, не видел никакой документации о том, что такое ожидаемое поведение. Поэтому я думаю, что вам будет трудно найти кого-либо, кто мог бы дать окончательный ответ о том, является ли какое-либо из поведения ошибкой. Но я согласен, что это, безусловно, непоследовательно и кажется мне, по крайней мере, недостатком дизайна.

Я бы не охарактеризовал ситуацию как хаотичную в том, что поведение определенной команды, кажется, воспроизводимой. Но командир.EXE непоследователен в том, что я не вижу никакого способа предсказать, как любая команда ведет себя без тестирования.

у меня нет объяснений, но у меня есть некоторые уточненные классификации поведения.

перенаправление stdout или stderr на stdin работает отлично, если ни одна команда не пытается что-либо записать в перенаправленный вывод. Странное поведение возникает только при попытке внутренней команды запись в stdout или stderr после перенаправления в stdin.

я расширил ваши тесты, и видели следующие различные поведения:

Перенаправленный STDERR 2>&01

Я не делал исчерпывающего тестирования, но каждая внутренняя команда, которую я тестировал, которая записывает в stderr, немедленно завершит сеанс команды, если stderr был перенаправлен на stdin. Примеры включают в себя:

cd invalidPath 2>&0
vol x 2>&0
copy nonExistentFile 2>&0
move nonExistentFile 2>&0
set nonExistentVariable 2>&0
dir nonExistentFile 2>&0

то, что вы думали, было исключением на самом деле никогда не пишет в stderr. Попробуйте выполнить следующие действия без перенаправления, и вы увидите сообщение об ошибке:

dir nonExistentFIle *

так что нет никаких причин для команды, чтобы завершить сеанс команды, если stderr перенаправляется на стандартный ввод.

DIR выводит сообщение об ошибке, только если не удается найти соответствующий файл по всем предоставленным маскам файлов.

:: This prints an error message
dir nonExistentFile1 nonExistentFile2

:: So this terminates the command session
dir nonExistentFile1 nonExistentFile2 2>&0



Перенаправленный STDOUT 1>&0

здесь поведение я видел для перенаправления вывода:

1) выход исчезает в эфир, без какого-либо сообщения об ошибке.

примеры:

vol >&0
copy /-y file1 existingFile2 >&0
move /-y file1 existingFile2 >&0



2) Вывод не выполняется и выводится сообщение об ошибке stderr. Одна команда может создавать несколько сообщений, по одному для каждой неудачной попытки записи в stdout.

примеры:

cd >&0
echo Hello >&0

:: This generates 2 error messages, one for the time,
:: and another for the subsequent empty line
time /t >&0



3) выход терпит неудачу, и пакетная обработка завершенный. Активные SETLOCAL остаются в силе, даже после завершения пакета, если ошибка происходит в пределах вызываемой подпрограммы. В этом отношении он ведет себя так же, как фатальная синтаксическая ошибка.

до сих пор я видел только одну команду демонстрируют такое поведение:

dir >&0

Я ожидал бы, что команда DIR создаст сообщение об ошибке для каждой попытки вывода строки. Но это, кажется, завершается после сбоя на первой строке, и пакетная обработка также прерванный.



4) некоторые команды демонстрируют несколько моделей поведения.

примеры:

:: This SET command generates an error message for each
:: defined variable (behavior 2)
set >&0

:: But this SET command fails to display the prompt without
:: error message (behavior 1). Note that the echo of user input
:: is written directly to :con. It does not use stdout or stderr.
set "var=prompt" >&0

:: A single PAUSE exhibits both behaviors 1 and 2. The prompt to
:: press a key simply dissapears, and the echo of the user input
:: generates an error. Note that in this case, the echo of user
:: input is written to stdout.
pause >&0
4
отвечен dbenham 2023-03-12 09:19

Я впервые обнаружил эту ошибку случайно в 2010 году. В конечном счете я обнаружил свою ошибку-перенаправление stderr в поток 0 (stdin для текущего процесса) не имеет логического смысла и cmd.exe не было обработчика для этого сценария, так что он просто выручил. Правильный синтаксис:

dir 2> nul (если бы я только хотел перенаправить ошибку)

или

dir 2 > nul 1>&2 (Если я также хотел перенаправить успешный вывод).

в основном просто необработанное исключение в CMD.EXE для любых встроенных команд. Вот моя рецензия на несколько лет назад:http://dnlongen.blogspot.com/2013/05/how-to-crash-windows-shell.html

0
отвечен David Longenecker 2023-03-12 11:36

взгляните на https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true

>& Writes the output from one handle to the input of another handle.
<& Reads the input from one handle and writes it to the output of another handle.

оператор & redirection дублирует вывод или ввод с одного указанный дескриптор для другого указанного дескриптора. При дублировании дескриптор, дублирующий все характеристики исходного вхождения ручки. Например, если дескриптор имеет доступ только для записи, все дубликаты этого дескриптора имеют доступ только для записи. Дублировать нельзя дескриптор с доступом только для чтения в дескриптор с доступом только для записи.

0
отвечен joanmib 2023-03-12 13:53

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх