표준 입력 (> & 0)에 대한 Windows cmd 출력 리디렉션


4

~에서 의문 Stackoverflow에, 나는 /에서 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로 보낸 텍스트를 숨기고 나머지 정보를 인쇄합니다.

그래서 문제는 이것이 버그일까요? 어딘가에 문서화되어 있고 발견 할 수 없거나 예상되는 행동이며 빠진 부분이 있습니다.

답변:


4

CMD.EXE가 비현실적으로 문서화되지 않았다는 것을 감안할 때 예상되는 동작이 무엇인지 확신 할 수 없습니다. 기대 한 행동이 무엇인지에 대한 어떠한 문서도 보지 못했습니다. 그래서 나는 당신이 어떤 행동이 버그인지 여부에 관해 확실한 답을 줄 수있는 사람을 찾기 위해 열심히 노력할 것이라고 생각합니다. 그러나 나는 확실히 일관성이없고 적어도 디자인상의 결함 인 것 같다.

나는 특정 명령의 행동이 재현 될 수있는 것처럼 혼란스러운 상황을 특성화하지는 않을 것이다. 그러나 CMD.EXE는 어떤 명령이 테스트없이 어떻게 작동 하는지를 예측할 수있는 방법을 볼 수 없다는 점에서 일관성이 없습니다.

나는 어떤 설명도하지 않지만, 나는 약간의 세련된 행동 분류를 가지고있다.

명령이 실제로 리디렉션 된 출력에 아무 것도 쓰지 않으려는 경우 stdout 또는 stderr를 stdin으로 리디렉션하면 완벽하게 작동합니다. 비정상적인 동작은 내부 명령이 표준 입력으로 리디렉션 된 후 stdout 또는 stderr에 쓰려고 할 때만 발생합니다.

나는 당신의 시험을 연장했고 다음과 같은 별개의 행동을 보았습니다 :

리디렉션 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이 stdin으로 재 지정되는 경우 명령 세션을 종료 할 명령의 이유가 없습니다.

DIR은 제공된 모든 파일 마스크에서 일치하는 파일을 찾지 못한 경우에만 오류 메시지를 인쇄합니다.

:: This prints an error message
dir nonExistentFile1 nonExistentFile2

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


리디렉션 된 STDOUT 1>&0

다음은 리디렉션 된 stdout에 대해 본 행동입니다.

1) 출력이 오류 메시지없이 ether로 사라집니다.

예 :

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은 일괄 처리 종료 후에도 CALLed 서브 루틴 내에서 오류가 발생해도 그대로 유지됩니다. 이와 관련하여 치명적인 구문 오류와 유사합니다.

지금까지 나는 단지 하나의 명령이이 동작을 보임을 보았습니다 :

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

당연하지. 나는 보지 못했다. dir 명령이 발견되면 stderr에 기록하지 않습니다. 그리고 네, 일치하지 않는 정확한 용어입니다, 감사합니다.
MC ND

0

나는이 버그를 2010 년 실수로 처음 발견했습니다. stderr을 0 스트림 (현재 프로세스의 stdin)으로 리다이렉트하는 것은 논리적으로 의미가 없으며 cmd.exe에는 해당 시나리오의 핸들러가 없었기 때문에 실수를 발견했습니다. 아웃. 올바른 구문은 다음과 같습니다.

dir2 & gt; nul (오류 만 리디렉션하려는 경우)

또는

dir2> nul1 & amp; 2 (성공적인 출력을 재전송하기를 원한다면).

기본적으로 CMD.EXE에서 모든 기본 제공 명령에 대한 처리되지 않은 예외입니다. 몇 년 전 제가 작성한 글은 다음과 같습니다. http://dnlongen.blogspot.com/2013/05/how-to-crash-windows-shell.html


너. 이것은 실수가 아니 었습니다. 당신은 때때로 디버거를 무언가에 붙이고 플레이 할 수있는 가능성 / 시간을 가지고 있습니다. 이전의 테스트에서 명령 프로세서가 stderr에 기록 할 수 없다면 (직접 실행해서는 안됨) 직접 종료한다고 알고 있습니다. 내가 보지 못했던 것은 "때로는"그것이 일어나지 않는 이유입니다. dbenham은 내가 보지 못했던 것을 지적하면서 "문제가있는"사례가 stderr에 쓰지 않았 음을 지적합니다.
MC ND

0

보세요 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.

& amp; 리디렉션 연산자는 출력 또는 입력을 복제합니다.   지정된 핸들을 다른 지정된 핸들에 지정합니다. 복제 할 때   처리하면 원래 발생의 모든 특성이 복제됩니다.   핸들의 예를 들어, 핸들에 쓰기 전용 액세스 권한이있는 경우 모두   해당 핸들의 중복에는 쓰기 전용 액세스 권한이 있습니다. 복제 할 수 없습니다.   쓰기 전용 액세스가있는 핸들에 대한 읽기 전용 액세스가있는 핸들.


질문을 다시 읽으십시오. 당신의 대답은 아니 원래의 질문에 답하십시오. 당신은 OP 질문에서 이상한 행동을 설명하려고 시도하지 않습니다. 답이 좋았는지 확인하기 위해 대답을 읽으십시오.
DavidPostill

죄송합니다. 내 말이 맞습니다. 제 대답은 때때로 오류를 반환하고 때때로 오류가 발생하지 않거나 충돌하는 이유를 설명하지 않습니다. 항상 오류 ( "쓸 수 없습니다 ...")를 예상 된 동작으로 반환해야하므로 @ David-Longenecker가 버그라고 생각하고 블로그에서 설명합니다. dnlongen.blogspot.com/2013/05/how-to-crash-windows-shell.html
joanmib
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.