다음과 같은 간단한 배치 파일이 있습니다.
에코 오프 taskkill / im "test.exe"/ f> nul 중지
“test.exe”가 실행되고 있지 않으면 다음 메시지가 표시됩니다.
오류 : 프로세스 "test.exe"를 찾을 수 없습니다.
출력을 NUL로 리디렉션 했는데도이 오류 메시지가 표시되는 이유는 무엇입니까?
그 출력을 어떻게 억제 할 수 있습니까?
답변
오류 메시지가 자주 방문한 기록이있어 stderr
하지stdout
.
호출을 다음과 같이 변경하십시오.
taskkill /im "test.exe" /f >nul 2>&1
그리고 모두 더 좋아질 것입니다.
이는 stdout
파일 설명자 1이고 stderr
관례에 따라 파일 설명자 2 이기 때문에 작동합니다 . (0은 stdin
우연히도입니다.) 2>&1
null 장치로 방금 리디렉션 된 새 값 1에서 출력 파일 설명자 2를 복사합니다.
이 구문은 (느슨하게) 많은 Unix 셸에서 차용되었지만 셸 구문과 CMD.EXE 사이에 미묘한 차이가 있으므로주의해야합니다.
업데이트 : OP가 NUL
내가 여기에 쓰고 있는 “파일”이라는 이름의 특수한 특성을 이해한다는 것을 알고 있지만 댓글 작성자는 이해하지 않았으므로 해당 측면에 대해 좀 더 자세히 설명하겠습니다.
MSDOS의 초기 릴리스로 돌아가서 특정 파일 이름은 파일 시스템 커널에 의해 선점되고 장치를 참조하는 데 사용되었습니다. 그 이름의 최초의 목록을 포함 NUL
, PRN
, CON
, AUX
과 COM1
를 통해 COM4
. NUL
null 장치입니다. 읽기 또는 쓰기를 위해 항상 열 수 있으며, 모든 양을 쓸 수 있으며 읽기는 항상 성공하지만 데이터를 반환하지 않습니다. 나머지는 병렬 프린터 포트, 콘솔 및 최대 4 개의 직렬 포트를 포함합니다. MSDOS 5부터는 예약 된 이름이 몇 개 더 있었지만 기본 규칙은 매우 잘 확립되어 있습니다.
Windows가 만들어 졌을 때 MSDOS 커널 위에 상당히 얇은 응용 프로그램 전환 계층으로 시작되었으므로 동일한 파일 이름 제한이 적용되었습니다. 윈도우 NT는 그 자체에 진정한 운영체제로 만들 때, 이름을 좋아 NUL
하고 COM1
너무 널리 제거를 허용하는 작업을 가정했다. 그러나 새로운 장치가 항상 실제 파일 이름의 향후 사용자를 차단하는 이름을 갖게된다는 생각은 분명히 불합리합니다.
Windows NT 및 이후의 모든 버전 (2K, XP, 7 및 현재 8)은 모두 커널 코드에서 훨씬 더 정교한 NT 네임 스페이스 를 사용하고 신중하게 구성되고 이식성이 뛰어난 사용자 공간 코드를 사용합니다. 해당 이름 공간에서 장치 드라이버는 \Device
폴더를 통해 볼 수 있습니다 . 필요한 이전 버전과의 호환성을 지원하기 위해 \DosDevices
모든 파일 시스템 폴더에 예약 된 파일 이름 목록을 구현하는 폴더를 사용하는 특수 메커니즘이 있습니다. 사용자 코드는 일반적인 Win32 API 아래의 API 계층을 사용하여이 내부 이름 공간을 탐색 할 수 있습니다. 커널 네임 스페이스를 탐색하기위한 좋은 도구 는 Microsoft의 SysInternals 그룹의 WinObj 입니다.
Windows에서 파일 (및 장치)의 법적 이름을 둘러싼 규칙에 대한 전체 설명을 보려면 MSDN의이 페이지가 유익하고 벅차게 될 것입니다. 규칙은 당연한 것보다 훨씬 더 복잡하며 “법적인 정규화 된 경로 이름이 얼마나 긴가?”와 같은 간단한 질문에 실제로 대답하는 것은 불가능합니다.
답변
대신이 스크립트를 사용하십시오.
@taskkill/f /im test.exe >nul 2>&1
@pause
뭐라고 2>&1
부분은 실제로 않습니다, 그것은 리디렉션이다 stderr
출력을 stdout
. 아래에서 더 잘 설명하겠습니다.
@ taskkill / f / im test.exe> nul 2> & 1
“test.exe”작업을 종료합니다. 로 리디렉션 stderr
합니다 stdout
. 그런 다음로 리디렉션 stdout
합니다 nul
.
@중지
Press any key to continue . . .
누군가 키를 누를 때까지 일시 중지 메시지를 표시합니다 .
참고 : @
기호는 각 명령에 대한 프롬프트를 숨기고 있습니다. 이 방법으로 최대 8 바이트를 저장할 수 있습니다.
스크립트의 가장 짧은 버전은 다음과 같을 수 있습니다.
@taskkill/f /im test.exe >nul 2>&1&pause
이 &
문자는 처음에는 리디렉션에 사용되고 두 번째에는 명령을 구분하는 데 사용됩니다.
한 @
줄에 두 번 문자가 필요하지 않습니다. 이 코드는 게시 한 코드가 49 바이트 임에도 불구하고 40 바이트에 불과합니다! 실제로 9 바이트를 절약했습니다. 더 깨끗한 코드를 보려면 위를보세요.
답변
mysqldump는 다음과 함께 작동하지 않습니다 : > nul 2> & 1
대신 사용 : 2> nul
이것은 stderr 메시지를 억제합니다 : “경고 : 명령 줄 인터페이스에서 암호를 사용하는 것은 안전하지 않을 수 있습니다.”
답변
대신 이렇게 할 수도 있습니다.
tasklist | find /I "test.exe" > nul && taskkill /f /im test.exe > nul