Основы BAT файлов. Справка по команде if и ее параметрам

Обработка условий в пакетных программах

Синтаксис

if [not ] errorlevel число команда [ else выражение ]

if [not ] строка1 == строка2 команда [ else выражение ]

if [not ] exist имя_файла команда [ else выражение ]

Если расширения командного процессора разрешены, следует использовать следующий синтаксис:

if [/i ] строка1 оп_сравнения строка2 команда [else выражение ]

if cmdextversion число команда [else выражение ]

if defined переменная команда [else выражение ]

Параметры

not Задает выполнение команды только в случае невыполнения условия. errorlevel число Условие выполняется, если предыдущая команда, обработанная интерпретатором команд Cmd.exe, завершилась с кодом, равным или большим числа . команда Команда, которая должна быть обработана в случае выполнения условия. строка1 == строка2 Условие выполняется, если строки строка1 и строка2 совпадают. Строки могут быть заданы явно или могут быть пакетными переменными (например, %1 ). Явно заданные строки нет необходимости заключать в кавычки. exist имя_файла Условие выполняется, если существует файл с именем имя_файла . оп_сравнения Трехзначный оператор сравнения. В следующей таблице перечислены допустимые значения оп_сравнения .

/i Сравнение строк без учета регистра знаков. Параметр /i можно использовать в конструкции string1 == string2 команды if . Эти сравнения являются общими. Если и строка1 , и строка2 состоят из цифр, строки преобразовываются в числа и выполняется сравнение чисел. cmdextversion число Условие выполняется, только если номер внутренней версии, связанный с расширениями командного процессора Cmd.exe, равен или больше числа . первая версия имела номер 1. Номер версии увеличивается на 1 при внесении в расширения командного процессора значительных изменений. Условие с cmdextversion не выполняется, если расширения командного процессора запрещены (по умолчанию они разрешены). defined переменная Условие выполняется, если переменная определена. выражение Команда и все ее параметры для обработке в командной строке при выполнении оператора else . /? Отображение справки в командной строке.

Заметки

  • Если условие, заданное в команде if , выполняется, будет выполнена команда, следующая за условием. Если условие не выполняется, команда, заданная в операторе if , пропускается, а управление переходит к команде оператора else , если она задана.
  • Когда программа завершается, она возвращает код завершения. С помощью параметра errorlevel коды завершения можно использовать в качестве условий.
  • Использование команды defined переменная

    При использовании команды defined переменная добавляются следующие три переменные: %errorlevel% , %cmdcmdline% и %cmdextversion% .

    %errorlevel% errorlevel , если только уже не существует переменная среды с именем ERRORLEVEL. В этом случае будет использовано ее значение. В следующем примере показано использование значения errorlevel после выполнения пакетной программы:

    goto answer%errorlevel% :answer0 echo Код возврата программы равен 0:answer1 echo Код возврата программы равен 1 goto end:end echo Готово!

    Операторы сравнения оп_сравнения также можно использовать следующим образом:

    if %errorlevel% LEQ 1 goto okay

    %cmdcmdline% замещается исходной командной строкой, переданной Cmd.exe, до ее обработки в Cmd.exe, если только уже не существует переменная среды с именем cmdcmdline . В этом случае будет использовано значение cmdcmdline .

    %cmdextversion% замещается строковым представлением текущего значения cmdextversion , если только уже не существует переменная среды с именем CMDEXTVERSION. В этом случае будет использовано ее значение.

  • Использование оператора else

    Оператор else должен размещаться в той же строке, что и команда if . Пример:

    IF EXIST имя_файла. (del имя_файла.) ELSE (echo имя_файла. отсутствует.)

    del должна заканчиваться новой строкой:

    IF EXIST имя_файла. del имя_файла. ELSE echo имя_файла. отсутствует

    Приведенный ниже пример не будет работать, поскольку команда else должна находиться в той же строке, что и команда if :

    IF EXIST имя_файла. del имя_файла. ELSE echo имя_файла. отсутствует

    Если необходимо разместить всю инструкцию в одной строке, можно использовать следующую правильную форму исходной инструкции:

    IF EXIST имя_файла (del имя_файла) ELSE echo имя_файла отсутствует

Примеры

Если файл Product.dat не удается найти, появится следующее сообщение:

if not exist product.dat echo Не найден файл данных

Если в приведенном ниже примере при форматировании диска в дисководе A возникнет ошибка, будет выведено сообщение об ошибке:

:begin @echo off format a: /s if not errorlevel 1 goto end echo Ошибка при форматировании. :end echo Конец пакетной программы.

Если ошибка не возникнет, сообщение об ошибке выведено не будет.

Команда if не может быть использована непосредственно для проверки существования каталога, но в каждом каталоге существует устройство (NUL). Следовательно, существование каталога может быть проверено, как показано ниже. В следующем примере проверяется наличие каталога:

if exist c:mydir\nul goto process

В этой статье:

  • Определение переменных
  • Переменные командной строки (параметры вызова bat-файла)
  • Оператор условия IF
  • Функции
  • Использование возвращаемых значений (обработка кода завершения программы)

Определение переменных

SET <Имяпеременной>=<Значениепеременной>

Оператор SET представляет собой расширение возможностей работы с параметрами в операционной системе. Он задает переменную, значение которой подставляется вместо ее имени при любом использовании этого имени между знаками процента. Так, если задано (переменная, которую требуют многие игры, использующие звуковую карту компьютера):

SET BLASTER=A220 I5 D1 P330

то при использовании в пакетном файле следующей конструкции:

ECHO %BLASTER%

на экран будет выведено "A220 I5 D1 P330". Переменные, определенные с помощью оператора SET называются переменными окружения среды (environment) и являются видимыми после выполнения до перезапуска DOS (если не изменять ее вручную в памяти). То есть, ее можно использовать из одного пакетного файла или программы после задания в другом. Наиболее известной является переменная PATH, представляющая собой набор путей для быстрого поиска файлов. Она задается в файле autoexec.bat.

Переменные командной строки
(параметры вызова bat-файла)

%<цифра 0-9>

Как и в любом языке, в языке пакетных файлов возможно использование переменных, полученных в качестве параметров bat-файла.

Всего может быть 10 одновременно существующих независимых переменных. Для написания сложных программ это довольно мало, хотя для обычной работы часто хватает и 3-4. Значение переменной равно значению соответствующего параметра из командной строки. Переменная %0 будет содержать имя.bat-файла и, если вы указали, путь к нему. То есть, если вы запустили файл abc.bat со следующими параметрами:

abc.bat a bc def

то переменная %0 будет содержать значение abc.bat , %1 будет содержать значение a, %2 будет содержать bc , а %3 - def . Это свойство широко используется для создания универсальных пакетных файлов при работе с повторяющимися операциями.

Чтобы получить более чем 10 переменных из командной строки, можно воспользоваться командой SHIFT .

Команда SHIFT позволяет использовать число параметров командной строки далее 10. Однако, при этом теряются соответственно более ранние параметры. Иными словами, команда SHIFT сдвигает все значения переменных на один шаг влево. То есть, переменная %0 будет содержать значение, содержавшееся до этого в переменной %1 , а переменная %1 - значение переменной %2 до сдвига. Однако, данная операция является необратимой, то есть, невозможно сдвинуть переменные обратно.

Оператор условия IF

К счастью, командный интерпретатор cmd.exe современных ОС Windows 2000 и старше поддерживает блоки команд в конструкциях ветвления, что устраняет необходимость применения IF с метками. Блоки команд заключаются в круглые скобки. Выглядит это так (имитируя C/C++ indentation style):

if condition (

Rem Команды ветки ‘then’

Rem ...

) else (

Rem Команды ветки ‘else’

Rem ...

Конкретный пример использования:

@echo off

set BUILDMODE=%1

if "%BUILDMODE%" == "" (

Echo FAIL: Аргумент является обязательным ^(--debug, --release^)

Exit /b 1

rem Удаляем из аргумента все дефисы для упрощения обработки

set BUILDMODE=%BUILDMODE:-=%

if "%BUILDMODE%" == "debug" (

Set CCFLAGS=/Od /MDd /Z7

) else (

Set CCFLAGS=/O2 /MD

На мой взгляд, с этим уже вполне можно жить. Но, как всегда, жизнь не так проста, как кажется. Есть одна проблема. Переменные, использующиеся в блоках then и else, раскрываются перед началом выполнения этих блоков, а не в процессе выполнения. В приведенном примере это не вызывает никаких проблем, однако в следующем вызовет:

if "%BUILDMODE%" == "debug" (

Echo INFO: Устанавливаем debug-режим окружения

Set OPTFLAGS=/Od

Set CCFLAGS=%OPTFLAGS% /MDd /Z7

) else (

Echo INFO: Устанавливаем release-режим окружения

Set OPTFLAGS=/O2

Set CCFLAGS=%OPTFLAGS% /MD

Загвоздка в том, что в обоих блоках подстановка переменной OPTFLAGS произойдет до того, как она будет изменена в процессе выполнения этого блока. Соответственно, в CCFLAGS будет подставлено то значение, которое OPTFLAGS имела на момент начала выполнения данного if-блока.

Решается эта проблема путем использования отложенного раскрытия переменных. Переменные, заключенные в !…! вместо %…% , будут раскрыты в их значения только в момент непосредственного использования. Данный режим по умолчанию отключен. Включить его можно либо использованием ключа /V:ON при вызове cmd.exe , либо использованием команды:

в тексте самого bat-файла. Второй способ мне представляется более удобным – не очень здорово требовать от кого-то запуска твоего сценария с определенным параметром.

С учетом сказанного предыдущий «неправильный» пример может быть исправлен так:

setlocal enabledelayedexpansion

if "%BUILDMODE%" == "debug" (

Echo INFO: Setting up debug mode environment

Set OPTFLAGS=/Od

Set CCFLAGS=!OPTFLAGS! /MDd /Z7

) else (

Echo INFO: Setting up release mode environment

Set OPTFLAGS=/O2

Set CCFLAGS=!OPTFLAGS! /MD

Вот теперь это почти полноценный if-then-else блок. Почти, потому что если в одной из команд echo у вас встретится закрывающая круглая скобка, то вам необходимо заэкранировать ее символом ^, иначе синтаксический анализатор путается…

Но в любом случае, это гораздо лучше безумного количества меток и переходов.

Функции

А можно создать в bat-файле функцию? Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно.

Есть особый синтаксис команды call , который позволяет перейти на метку в этом же bat-файле с запоминанием места, откуда был произведен этот вызов:

call:метка аргументы

Возврат из функции производится командой:

exit /b [опциональный код возврата]

Ключ /b здесь очень важен: без него будет произведен выход не из функции, а из сценария вообще.

За подробностями наберите в командной строке:

call /?

exit /?

Что интересно, команда call с таким синтаксисом поддерживает рекурсивные вызовы с автоматическим созданием нового фрейма для переменных аргументов %0-%9. Иногда это может быть полезным. Вот классический пример рекурсивного подсчета факториала на командном языке:

@echo off

call:factorial %1

echo %RESULT%

exit

rem Функция для подсчета значения факториала

rem Вход:

rem %1 Число, для которого необходимо подсчитать факториал

rem Выход:

rem %RESULT% Значение факториала

:factorial

if %1 == 0 (

Set RESULT=1

Exit /b

if %1 == 1 (

Set RESULT=1

Exit /b

set /a PARAM=%1 - 1

call:factorial %PARAM%

set /a RESULT=%1 * %RESULT%

exit /b

Пример работы:

> factorial.bat 10

3628800

Использование возвращаемых значений
(обработка кода завершения программы)

Любая программа при завершении своей работы возвращает операционной системе код своего завершения. Принято при успешном завершении возвращать ноль, иначе - код ошибки. Иногда, или, вернее, часто, программа "сознательно" возвращает ненулевое значение для того, чтобы в пакетном файле можно было "узнать" некоторые подробности ее работы. Например, программа возвращает код нажатой клавиши, а.bat-файл по нему выполняет различные действия.

Каким же образом пакетный файл может узнать код завершения выполненной программы? Для этого предусмотрено ключевая переменная ERRORLEVEL .

Пример пакетного файла с errorlevel"ами:

@ECHO OFF

REM Запускаем программу prg1.exe

PRG1.EXE

REM Анализ кода завершения

IF ERRORLEVEL 2 GOTO FILENOTFOUND

IF ERRORLEVEL 1 GOTO WRITEERROR

IF ERRORLEVEL 0 GOTO EXITOK

GOTO ONEXIT

:FILENOTFOUND

ECHO Ошибка! Файл не найден!

GOTO ONEXIT

:WRITEERROR

ECHO Ошибка записи!

GOTO ONEXIT

:EXITOK

ECHO Программа завершена благополучно.

GOTO ONEXIT

:ONEXIT

Обратите внимание - анализ кода завершения начинается не с нуля, а с максимально возможного значения. Дело в том, что подобная проверка означает: "если errorlevel больше или равен значению, то...". То есть, если мы будем проверять, начиная с нуля, любое значение будет истинным на первой же строке, что неверно.

Это самая распространенная ошибка в подобного рода программах.

Обработка условий в пакетных программах.

Синтаксис

if [not ] errorlevel число команда [ else выражение ]

if [not ] строка1 == строка2 команда [ else выражение ]

if [not ] exist имя_файла команда [ else выражение ]

Если расширения командного процессора разрешены, следует использовать следующий синтаксис:

if [/i ] строка1 оп_сравнения строка2 команда [else выражение ]

if cmdextversion число команда [else выражение ]

if defined переменная команда [else выражение ]

Параметры

not Задает выполнение команды только в случае невыполнения условия. errorlevel число Условие выполняется, если предыдущая команда, обработанная интерпретатором команд Cmd.exe, завершилась с кодом, равным или большим числа . команда Команда, которая должна быть обработана в случае выполнения условия. строка1 == строка2 Условие выполняется, если строки строка1 и строка2 совпадают. Строки могут быть заданы явно или могут быть пакетными переменными (например, %1 ). Явно заданные строки нет необходимости заключать в кавычки. exist имя_файла Условие выполняется, если существует файл с именем имя_файла . оп_сравнения Трехзначный оператор сравнения. В следующей таблице перечислены допустимые значения оп_сравнения . /i Сравнение строк без учета регистра знаков. Параметр /i можно использовать в конструкции string1 == string2 команды if . Эти сравнения являются общими. Если и строка1 , и строка2 состоят из цифр, строки преобразовываются в числа и выполняется сравнение чисел. cmdextversion число Условие выполняется, только если номер внутренней версии, связанный с расширениями командного процессора Cmd.exe, равен или больше числа . первая версия имела номер 1. Номер версии увеличивается на 1 при внесении в расширения командного процессора значительных изменений. Условие с cmdextversion не выполняется, если расширения командного процессора запрещены (по умолчанию они разрешены). defined переменная Условие выполняется, если переменная определена. выражение Команда и все ее параметры для обработке в командной строке при выполнении оператора else . /? Отображение справки в командной строке.

Заметки

  • Если условие, заданное в команде if , выполняется, будет выполнена команда, следующая за условием. Если условие не выполняется, команда, заданная в операторе if , пропускается, а управление переходит к команде оператора else , если она задана.
  • Когда программа завершается, она возвращает код завершения. С помощью параметра errorlevel коды завершения можно использовать в качестве условий.
  • Использование команды defined переменная

    При использовании команды defined переменная добавляются следующие три переменные: %errorlevel% , %cmdcmdline% и %cmdextversion% .

    %errorlevel% errorlevel , если только уже не существует переменная среды с именем ERRORLEVEL. В этом случае будет использовано ее значение. В следующем примере показано использование значения errorlevel после выполнения пакетной программы:

    goto answer%errorlevel%
    :answer0
    echo Код возврата программы равен 0
    :answer1
    echo Код возврата программы равен 1
    goto end
    :end
    echo Готово!

    Операторы сравнения оп_сравнения также можно использовать следующим образом:

    If %errorlevel% LEQ 1 goto okay

    %cmdcmdline% замещается исходной командной строкой, переданной Cmd.exe, до ее обработки в Cmd.exe, если только уже не существует переменная среды с именем cmdcmdline . В этом случае будет использовано значение cmdcmdline .

    %cmdextversion% замещается строковым представлением текущего значения cmdextversion , если только уже не существует переменная среды с именем CMDEXTVERSION. В этом случае будет использовано ее значение.

  • Использование оператора else

    Оператор else должен размещаться в той же строке, что и команда if . Пример:

    IF EXIST имя_файла. (del имя_файла.) ELSE (echo имя_файла. отсутствует.)

    del должна заканчиваться новой строкой:

    IF EXIST имя_файла. del имя_файла. ELSE echo имя_файла. отсутствует

    Приведенный ниже пример не будет работать, поскольку команда else должна находиться в той же строке, что и команда if :

    IF EXIST имя_файла. del имя_файла. ELSE echo имя_файла. отсутствует

    Если необходимо разместить всю инструкцию в одной строке, можно использовать следующую правильную форму исходной инструкции:

    IF EXIST имя_файла (del имя_файла) ELSE echo имя_файла отсутствует

Примеры

Если файл Product.dat не удается найти, появится следующее сообщение:

if not exist product.dat echo Не найден файл данных

Если в приведенном ниже примере при форматировании диска в дисководе A возникнет ошибка, будет выведено сообщение об ошибке:

:begin
@echo off
format a: /s
if not errorlevel 1 goto end
echo Ошибка при форматировании.
:end
echo Конец пакетной программы.

Если ошибка не возникнет, сообщение об ошибке выведено не будет.

Команда if не может быть использована непосредственно для проверки существования каталога, но в каждом каталоге существует устройство (NUL). Следовательно, существование каталога может быть проверено, как показано ниже. В следующем примере проверяется наличие каталога:

if exist c:mydir\nul goto process

Из одного командного файла можно вызвать другой, просто указав его имя. Например:

@ECHO OFF CLS REM Вывод списка log-файлов DIR C:\*.log REM Передача выполнения файлу f.bat f.bat COPY A:\*.* C:\ PAUSE

Однако в этом случае после выполнения вызванного файла управление в вызывающий файл не передается, то есть в приведенном примере команда

(и все следующие за ней команды) никогда не будет выполнена.

Для того, чтобы вызвать внешний командный файл с последующим возвратом в первоначальный файл, нужно использовать специальную команду CALL файл

Например:

@ECHO OFF CLS REM Вывод списка log-файлов DIR C:\*.log REM Передача выполнения файлу f.bat CALL f.bat COPY A:\*.* C:\ PAUSE

В этом случае после завершения работы файла f.bat управление вернется в первоначальный файл на строку, следующую за командой CALL (в нашем примере это команда COPY A:\*.* C:\ ).

Операторы перехода

Командный файл может содержать метки и команды GOTO перехода к этим меткам. Любая строка, начинающаяся с двоеточия:, воспринимается при обработке командного файла как метка. Имя метки задается набором символов, следующих за двоеточием до первого пробела или конца строки. Приведем пример.

Пусть имеется командный файл следующего содержания:

@ECHO OFF COPY %1 %2 GOTO Label1 ECHO Эта строка никогда не выполнится:Label1 REM Продолжение выполнения DIR %2

После того, как в этом файле мы доходим до команды

его выполнение продолжается со строки

REM Продолжение выполнения

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

Также для перехода к метке внутри текущего командного файла кроме команды GOTO можно использовать и рассмотренную выше команду CALL :

CALL:метка аргумента

При вызове такой команды создается новый контекст текущего пакетного файла с заданными аргументами, и управление передается на инструкцию, расположенную сразу после метки. Для выхода из такого пакетного файла необходимо два раза достичь его конца. Первый выход возвращает управление на инструкцию, расположенную сразу после строки CALL , а второй выход завершает выполнение пакетного файла. Например, если запустить с параметром "Копия-1" командный файл следующего содержания:

@ECHO OFF ECHO %1 CALL:2 Копия-2:2 ECHO %1

то на экран выведутся три строки:

Копия-1 Копия-2 Копия-1

Таким образом, подобное использование команды CALL очень похоже на обычный вызов подпрограмм (процедур) в алгоритмических языках программирования.

Операторы условия

С помощью команды IF … ELSE (ключевое слово ELSE может отсутствовать) в пакетных файлах можно выполнять обработку условий нескольких типов. При этом если заданное после IF условие принимает истинное значение, система выполняет следующую за условием команду (или несколько команд, заключенных в круглые скобки), в противном случае выполняется команда (или несколько команд в скобках), следующие за ключевым словом ELSE .

Проверка значения переменной

Первый тип условия используется обычно для проверки значения переменной. Для этого применяются два варианта синтаксиса команды IF :

IF строка1==строка2 команда1

(квадратные скобки указывают на необязательность заключенных в них параметров) или

IF строка1 оператор_сравнения строка2 команда

Рассмотрим сначала первый вариант. Условие строка1==строка2 (здесь необходимо писать именно два знака равенства) считается истинным при точном совпадении обеих строк. Параметр NOT указывает на то, что заданная команда выполняется лишь в том случае, когда сравниваемые строки не совпадают.

Строки могут быть литеральными или представлять собой значения переменных (например, %1 или %TEMP% ). Кавычки для литеральных строк не требуются. Например,

IF %1==%2 ECHO Параметры совпадают! IF %1==Петя ECHO Привет, Петя!

Отметим, что при сравнении строк, заданных переменными, следует проявлять определенную осторожность. Дело в том, что значение переменной может оказаться пустой строкой, и тогда может возникнуть ситуация, при которой выполнение командного файла аварийно завершится. Например, если вы не определили с помощью команды SET переменную MyVar , а в файле имеется условный оператор типа

IF %MyVar%==C:\ ECHO Ура!!!

то в процессе выполнения вместо %MyVar% подставится пустая строка и возникнет синтаксическая ошибка. Такая же ситуация может возникнуть, если одна из сравниваемых строк является значением параметра командной строки, так как этот параметр может быть не указан при запуске командного файла. Поэтому при сравнении строк нужно приписывать к ним в начале какой-нибудь символ, например:

IF -%MyVar%==-C:\ ECHO Ура!!!

С помощью команд IF и SHIFT можно в цикле обрабатывать все параметры командной строки файла, даже не зная заранее их количества. Например, следующий командный файл (назовем его primer.bat) выводит на экран имя запускаемого файла и все параметры командной строки:

@ECHO OFF ECHO Выполняется файл: %0 ECHO. ECHO Файл запущен со следующими параметрами... REM Начало цикла:BegLoop IF -%1==- GOTO ExitLoop ECHO %1 REM Сдвиг параметров SHIFT REM Переход на начало цикла GOTO BegLoop:ExitLoop REM Выход из цикла ECHO. ECHO Все.

Если запустить primer.bat с четырьмя параметрами:

primer.bat А Б В Г

то в результате выполнения на экран выведется следующая информация.

Формат командной строки:

IF ERRORLEVEL число команда

IF строка1==строка2 команда

IF EXIST имя_файла команда

Параметры:

NOT - Указывает, что Windows должна выполнить эту команду, только если условие является ложным.

ERRORLEVEL число - Условие является истинным, если код возврата последней выполненной программы не меньше указанного числа.

строка1==строка2 - Условие является истинным, если указанные строки совпадают.

EXIST имя_файла - Условие является истинным, если файл с указанным именем существует.

команда - Задает команду, выполняемую при истинности условия. За этой командой может следовать ключевое слово ELSE. В случае, если указанное условие ложно, будет выполнена команда, находящаяся после слова ELSE.

Предложение ELSE должно располагаться в той же строке, что и команда, следующая за ключевым словом IF. Например:

IF EXIST имя_файла. (
del имя_файла.
) ELSE (
echo имя_файла. missing.
)

Следующий пример содержит ОШИБКУ, поскольку команда del должна заканчиваться переходом на новую строку:

IF EXIST имя_файла. del имя_файла. ELSE echo имя_файла. Missing

Следующий пример также содержит ОШИБКУ, поскольку команда ELSE должна располагаться в той же строке, что и команда, следующая за IF:

IF EXIST имя_файла. del имя_файла.
ELSE echo имя_файла. missing
Вот правильный пример, где все команды расположены в одной строке:

IF EXIST имя_файла. (del имя_файла.) ELSE echo имя_файла. Missing

Изменение команды IF при включении расширенной обработки команд:

IF строка1 оператор_сравнения строка2 команда
IF CMDEXTVERSION число команда
IF DEFINED переменная команда

Где оператор_сравнения принимает следующие значения:

EQU - равно
NEQ - не равно
LSS - меньше
LEQ - меньше или равно
GTR - больше
GEQ - больше или равно,

А ключ /I , если он указан, задает сравнение текстовых строк без учета регистра. Ключ /I можно также использовать и в форме строка1==строка2 команды IF. Сравнения проводятся по общему типу данных, так что если строки 1 и 2 содержат только цифры, то обе строки преобразуются в числа, после чего выполняется сравнение чисел.

Условие CMDEXTVERSION применяется подобно условию ERRORLEVEL, но значение сравнивается с внутренним номером версии текущей реализации расширенной обработки команд. Первая версия имеет номер 1. Номер версии будет увеличиваться на единицу при каждом добавлении существенных возможностей расширенной обработки команд. Если расширенная обработка команд отключена, условие CMDEXTVERSION никогда не бывает истинно.

Условие DEFINED применяется подобно условию EXIST , но принимает в качестве аргумента имя переменной среды и возвращает истинное значение, если эта переменная определена.

Строка %ERRORLEVEL% будет развернута в строковое представление текущего значения кода ошибки ERRORLEVEL, за исключением ситуации, когда уже имеется переменная среды с именем ERRORLEVEL; в подобном случае подставляется значение этой переменной. Например, с помощью данной строки можно выполнить следующее:

goto answer%ERRORLEVEL%
:answer0
echo Получен код возврата 0
:answer1
echo Получен код возврата 1

Допускается и применение описанных выше операторов числового сравнения:

IF %ERRORLEVEL% LEQ 1 goto okay

Строка %CMDCMDLINE% будет развернута в исходную командную строку, переданную CMD.EXE до любой обработки, за исключением ситуации, когда уже определена переменная среды с именем CMDCMDLINE; в подобном случае подставляется значение этой переменной.

Строка %CMDEXTVERSION% будет развернута в строку, представляющую собой текущее значение CMDEXTVERSION, за исключением ситуации, когда уже имеется переменная среды с именем CMDEXTVERSION; в подобном случае подставляется значение этой переменной.

Примеры использования:

  • Создание пустого файла, имя которого задается параметром командной строки.

    Если параметр командной строки не задан, то пользователю выдается сообщение об ошибке.


    @echo off
    REM Проверить наличие имени файла, задаваемого в качестве параметра %1
    REM Если параметр %1 пустой – переход на метку error
    if "%1" EQU "" goto error
    REM Если параметр задан, создаем пустой файл, копированием из устройства nul
    copy nul "%1"
    exit
    :error
    ECHO File name required ! Must be - %~n0 filename.ext
    :exit

  • Командный файл, выполняющий опрос командой ping сетевых адресов в заданном диапазоне (192.168.1.1 – 192.168.1.254). Команда ping формирует значение переменной ERRORLEVEL равное нулю, если верно заданы параметры командной строки. То есть, определить доступность пингуемого IP-адреса методом анализа кода возврата ping не получится, поскольку он будет нулевым, независимо от того, отвечает ли пингуемое устройство, или нет. Поэтому, для решения данной задачи необходимо определить характерный признак, который присутствует в выводимых результатах только в том случае, когда пингуемое устройство доступно. Таким признаком может быть наличие строки символов "TTL" в выводе команды ping. Для определения признака можно использовать команду find в цепочке с командой ping .

    Примеры вывода для отвечающего и не отвечающего узлов:

    Ответ от 192.168.1.1: число байт=32 время=1мс TTL=64 - если устройство с данным IP-адресом доступно;
    Превышен интервал ожидания для запроса. - если устройство не отвечает;

    Команда find /I "TTL" возвращает код ERRORLEVEL равный 0 , если строка "TTL" присутствует в результате выполнения ping . Ключ /I имеет смысл использовать, чтобы результат не зависил от того, строчные или заглавные символы составляют строку "ttl".
    Результат работы командного файла записывается в текстовый файл iplist.txt

    @ECHO OFF
    REM Постоянная часть IP-адреса
    set IPTMP=192.168.1.
    REM Количество пингуемых узлов
    set N=254
    rem С какого адреса начать - начальное значение " хвоста " IP- адреса X.X.X.IPMIN
    set /A IPMIN=1
    ECHO %DATE% Опрос пингом %N% адресов начиная с %IPTMP%%IPMIN% >> iplist.txt
    rem M0 - метка для организации цикла
    :M0
    rem Переменная IPFULL - полное значение текущего IP-адреса
    set IPFULL=%IPTMP%%IPMIN%
    rem Если " хвост "больше N – перейти к завершению работы
    IF %IPMIN% GTR %N% GOTO ENDJOB
    ping -n 1 %IPFULL% | find /I "TTL"
    if %ERRORLEVEL%==0 Echo %IPFULL% >> iplist.txt
    rem Сформируем следующий IP-адрес
    set /A IPMIN=%IPMIN% + 1
    rem Перейдем на выполнение следующего шага
    GOTO M0
    rem Завершение работы
    :endjob
    exit

    Существуют некоторые особенности реализации командного интерпретатора CMD.EXE , которые необходимо учитывать при обработке значений переменных внутри циклов IF и FOR . Использование значений переменных внутри скобок, требует изменения стандартного режима интерпретации командного процессора. Разработчиками предусмотрена возможность запуска CMD.EXE с параметром /V:ON , что включает разрешение отложенного расширения переменных среды с применением символа восклицательного знака (! ) в качестве разделителя. То есть, параметр /V:ON разрешает использовать !var! в качестве значения переменной var во время выполнения внутри циклов команд FOR и IF . Но на практике чаще используется возможность локального включения данного режима внутри командного файла специальной директивой:

    Setlocal EnableDelayedExpansion

    После чего, можно обрабатывать принимаемые переменными значения внутри цикла, используя вместо знаков процента восклицательные знаки:

    FOR … (
    IF !ERRORLEVEL!==0 вместо %ERRORLEVEL%==0

    )

        В русскоязычной справке команды IF имеется ошибка, которая много лет переходит из версии в версию - вместо оператора EQU - равно , указано EQL - равно