Подавить вывод командной строки - PullRequest
106 голосов
/ 12 августа 2009

У меня есть простой командный файл, подобный этому:

echo off

taskkill /im "test.exe" /f > nul

pause

Если «test.exe» не запущен, я получаю это сообщение:

ERROR: The process "test.exe" not found.

Почему отображается это сообщение об ошибке, даже если я перенаправил вывод в NUL?

Как я могу подавить этот вывод?

Ответы [ 4 ]

190 голосов
/ 12 августа 2009

Поскольку сообщения об ошибках часто идут на stderr, а не stdout.

Измените вызов на этот:

taskkill /im "test.exe" /f >nul 2>&1

и все будет лучше.

Это работает, потому что stdout - это дескриптор файла 1, а stderr - это дескриптор файла 2 по соглашению. (0 - stdin, между прочим.) 2>&1 копирует дескриптор выходного файла 2 из нового значения 1, которое было только что перенаправлено на нулевое устройство.

Этот синтаксис (свободно) заимствован из многих оболочек Unix, но вы должны быть осторожны, поскольку между синтаксисом оболочки и CMD.EXE есть тонкие различия.

Обновление: Я знаю, что ОП понимает особую природу "файла" с именем NUL Я пишу здесь, но комментатор этого не сделал, и поэтому позвольте мне немного отступить подробно об этом аспекте.

Возвращаясь к самым ранним версиям MSDOS, некоторые имена файлов были вытеснены ядром файловой системы и использовались для обозначения устройств. Самый ранний список этих имен включал NUL, PRN, CON, AUX и COM1 - COM4. NUL - нулевое устройство. Его всегда можно открыть для чтения или записи, на него можно записать любое количество, и чтение всегда будет успешным, но данные не будут возвращены. Другие включают параллельный порт принтера, консоль и до четырех последовательных портов. В MSDOS 5 было еще несколько зарезервированных имен, но основное соглашение было очень хорошо разработано.

Когда Windows была создана, она начала существовать как довольно тонкий слой переключения приложений поверх ядра MSDOS и, таким образом, имела те же ограничения имени файла. Когда Windows NT создавалась как настоящая операционная система сама по себе, такие имена, как NUL и COM1, слишком широко использовались для их устранения. Однако идея о том, что новые устройства всегда будут получать имена, которые будут блокировать будущих пользователей этих имен для реальных файлов, явно неоправданна.

Windows NT и все последующие версии (2K, XP, 7 и теперь 8) следуют за использованием гораздо более сложного NT Namespace из кода ядра и тщательно сконструированного и крайне непереносимого пользовательского пространства код. В этом пространстве имен драйверы устройств видны через папку \Device. Для поддержки требуемой обратной совместимости существует специальный механизм, использующий папку \DosDevices, который реализует список зарезервированных имен файлов в любой папке файловой системы. Пользовательский код может просматривать это внутреннее пространство имен, используя уровень API ниже обычного Win32 API; Хороший инструмент для исследования пространства имен ядра - WinObj из группы SysInternals в Microsoft.

Для полного описания правил, касающихся юридических имен файлов (и устройств) в Windows, эта страница в MSDN будет и информативной, и устрашающей. Правила на много сложнее, чем они должны быть, и на самом деле невозможно ответить на некоторые простые вопросы, такие как "как долго длится самое длинное юридическое полное имя?"

6 голосов
/ 21 мая 2015

Используйте этот скрипт вместо:

@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
Символ & используется для перенаправления в первый раз и для разделения команд во второй раз.
Символ @ не требуется дважды в строке. Этот код составляет всего 40 байтов, несмотря на то, что вы разместили 49 байтов! Я на самом деле сэкономил 9 байтов. Для более чистого кода смотрите выше.

1 голос
/ 17 апреля 2015

mysqldump не работает с: > nul 2> & 1
Вместо этого используйте: 2> nul
Это подавляет сообщение stderr: «Предупреждение: использование пароля в интерфейсе командной строки может быть небезопасным»

0 голосов
/ 24 июня 2013

Вы можете сделать это вместо этого:

tasklist | find /I "test.exe" > nul && taskkill /f /im test.exe > nul
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...