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

Я проверяю наличие папки и, в зависимости от ее существования, хочу запускать разные команды:

DIR %MYDIR%\tmp > test.txt
IF ERRORLEVEL 1 (
      echo/FOLDER DOES NOT EXIST
) else (
      echo/FOLDER EXISTS
      )

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

The system cannot find the file specified.

Я хотел бы отобразить правильный вывод без получения ошибки.

3 ответа

Решение

Как насчет этого:

DIR %MYDIR%\tmp > nul 2>&1

"> nul" означает перенаправление стандартного вывода в файл nul (область битов).

"2>" используется для перенаправления стандартной ошибки (дескриптор 2). Таким образом, "2>&1" используется для перенаправления стандартной ошибки, что означает, что стандартный вывод (дескриптор 1 - так что "> null и 1> null одинаковы). В качестве альтернативы вы можете использовать" 2> nul ".

Возможно, вы столкнулись с общей проблемой, с которой я сталкивался много раз в своих собственных сценариях: не ожидая пробела в пути к файлу.

Значение переменной среды MYDIR может содержать пробел. Если в пути есть пробелы, большинство команд рассматривают его как несколько параметров, поскольку пробелы используются для разделения параметров. Итак, в вашем случае, если MYDIR C:\Documents and Settings\Jim\My Documents тогда ваш скрипт будет пытаться выполнить просмотр каталога по нескольким параметрам:

  • C: \ Documents
  • а также
  • Настройки \Jim\ Мои
  • документы

Попробуйте это в командной строке:

C:\> mkdir learn

C:\> cd learn

C:\learn> mkdir peas and carrots

C:\learn> dir

 Volume in drive C is OS
 Volume Serial Number is 7199-C950

 Directory of C:\learn

10/03/2012  07:26 PM    <DIR>          .
10/03/2012  07:26 PM    <DIR>          ..
10/03/2012  07:26 PM    <DIR>          and
10/03/2012  07:26 PM    <DIR>          carrots
10/03/2012  07:26 PM    <DIR>          peas

Хм, три папки с именами "горох", "и", "морковь" (отсортированы по алфавиту, как я предпочитаю команду dir). Чтобы создать папку с пробелами в имени, вы должны поставить кавычки вокруг имени папки:

C:\learn> mkdir "peas and carrots"

C:\learn> dir

 Volume in drive C is OS
 Volume Serial Number is 7199-C950

 Directory of C:\learn

10/03/2012  08:10 PM    <DIR>          .
10/03/2012  08:10 PM    <DIR>          ..
10/03/2012  07:26 PM    <DIR>          and
10/03/2012  07:26 PM    <DIR>          carrots
10/03/2012  07:26 PM    <DIR>          peas
10/03/2012  07:29 PM    <DIR>          peas and carrots
               0 File(s)              0 bytes
               6 Dir(s)  49,670,320,128 bytes free

Чтобы исправить эту проблему в вашем случае, добавьте кавычки вокруг пути к файлу / папке:

DIR "%MYDIR%\tmp" > test.txt

Это устраняет system cannot find the file specified даже если файл существует проблема.

К сожалению, если файл / папка действительно не существует, вы получите то же самое сообщение об ошибке. Если вы настаиваете на использовании DIR команду для этого, то вам придется перенаправить stderr поток. Вы уже перенаправили stdout с использованием > оператор перенаправления. Перенаправить stderr к тому же файлу ваша команда должна выглядеть так:

DIR "%MYDIR%\tmp" > test.txt 2>&1

Основываясь на выходных сообщениях вашего пакетного файла, я предполагаю, что вы заинтересованы только в определении, существует ли%MYDIR%\tmp, и вы на самом деле не хотите, чтобы список каталогов%MYDIR%\tmp оставался в файле с именем test.txt в текущем рабочем каталоге. Если вы просто проверяете, существует ли файл / папка, используйте DIR команда довольно плохой выбор. Если%MYDIR%\tmp является папкой, то скрипт будет тратить время на извлечение информации о каталоге для каждого файла в этой папке. Если в этой папке тысячи файлов, это может привести к заметной задержке. Кроме того, вы поместили файл с именем test.txt в текущую рабочую директорию, который вы должны удалить до выхода из сценария... вы знаете... при условии, что вы вообще не хотите этот файл.

Если вы просто хотите узнать, существует ли папка или файл, есть гораздо лучший выбор: if exist Команда идеально подходит для ваших нужд. Чтобы узнать больше о if введите в окне командной строки Windows: if /?

Пример:

C:\> if /?
Performs conditional processing in batch programs.

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

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

Пока вы читаете if В документации к команде вы можете встретить фразу "если расширения команд включены...". В большинстве систем расширения команд по умолчанию включены, но я все же хотел бы сделать вторую строку любого сценария. setlocal EnableExtensions, Первая строка @echo off, который быстро меняется на rem @echo off пока я не закончил отладку.

setlocal EnableExtensions Команда делает две вещи:

  1. гарантирует, что любые переменные среды, которые вы устанавливаете или изменяете в этом скрипте, не влияют на вызывающую среду.
  2. гарантирует, что расширения команд включены. Командные расширения хороши

Если вы хотите произвести впечатление на своих друзей, написав сложные и полезные сценарии в пакетном режиме (задача, которая когда-то считалась невозможной), внимательно прочитайте и возьмите встроенную документацию по каждой из этих команд:

  • если
  • задавать
  • вызов
  • за
  • CMD

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

Например: set Команда может быть использована для многих задач:

  1. Простое назначение:
    set myDir=C:\Foo

  2. Выполнение математики:
    set /a myCount=myCount + 1

  3. Подсказка для ввода:
    set /p myColor=What is favorite color

  4. Извлечение подстрок:
    set myCentury=%myYear:~0,2%

Вот как бы я написал твой сценарий

@echo off
setlocal EnableExtensions

if exist "%MyDir%\tmp" (
    echo Folder exists
) else (
    echo Folder does not exist
)

Удачи и счастливой охоты.

Использование exist вместо:

@echo off
if exist %MYDIR%\tmp (
  dir %MYDIR%\tmp > test.txt
  goto EndIt
)
echo %MYDIR%\tmp not found > test.txt
:EndIt
Другие вопросы по тегам