Перенаправление вывода из командной строки, чтобы сообщения об ошибках не отображались в командном окне
Я проверяю наличие папки и, в зависимости от ее существования, хочу запускать разные команды:
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
Команда делает две вещи:
- гарантирует, что любые переменные среды, которые вы устанавливаете или изменяете в этом скрипте, не влияют на вызывающую среду.
- гарантирует, что расширения команд включены. Командные расширения хороши
Если вы хотите произвести впечатление на своих друзей, написав сложные и полезные сценарии в пакетном режиме (задача, которая когда-то считалась невозможной), внимательно прочитайте и возьмите встроенную документацию по каждой из этих команд:
- если
- задавать
- вызов
- за
- CMD
Вы должны будете использовать все приемы и нюансы, которые эти команды могут предложить, чтобы написать действительно хорошие сценарии.
Например: set
Команда может быть использована для многих задач:
Простое назначение:
set myDir=C:\Foo
Выполнение математики:
set /a myCount=myCount + 1
Подсказка для ввода:
set /p myColor=What is favorite color
Извлечение подстрок:
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