Команда IF в пакетных файлах Windows 98 часто «не срабатывает» не из-за ошибки в логике скрипта, а из-за того, что интерпретатор COMMAND.COM этой системы поддерживает лишь базовый синтаксис MS-DOS: конструкции IF /I, IF DEFINED и сравнения чисел через EQU появились только в Windows NT/2000 и в среде Win9x недоступны. Если BAT-файл, написанный под современную Windows, выдаёт ошибку «Синтаксическая ошибка» или «Bad command or file name» на строке с условием — первым делом проверьте, не использованы ли расширенные ключи, которых в Windows 98 просто нет.

В этой статье разберём, какие формы IF реально работают в MS-DOS 7.x (командная строка Windows 95/98), как правильно строить ветвления с GOTO, как проверять существование файлов и коды возврата программ, а также какие типичные ошибки приводят к неработающим условиям.

Что такое IF в среде Windows 98

В Windows 98 пакетные файлы обрабатывает интерпретатор COMMAND.COM — наследник MS-DOS. Его синтаксис заметно беднее, чем у CMD.EXE из линейки Windows NT. Условный оператор поддерживает ровно три базовые формы:

  • 🔹 IF [NOT] ERRORLEVEL число команда — проверка кода возврата предыдущей программы;
  • 🔹 IF [NOT] строка1==строка2 команда — сравнение строк с учётом регистра;
  • 🔹 IF [NOT] EXIST имя_файла команда — проверка существования файла или каталога.

Каждая форма выполняет одну команду, стоящую после условия. Многострочных блоков в фигурных скобках или скобках, как в CMD.EXE, здесь нет — для сложной логики используется переход по метке через GOTO.

💡

В Windows 98 работают только три классические формы IF: ERRORLEVEL, сравнение строк и EXIST. Расширенный синтаксис CMD.EXE (IF /I, IF DEFINED, EQU/NEQ) недоступен.

Синтаксис и базовые примеры

Простейший скрипт с проверкой строки выглядит так:

@ECHO OFF

IF "%1"=="backup" GOTO BACKUP

ECHO Параметр не распознан

GOTO END

:BACKUP

ECHO Запуск резервного копирования...

:END

Обратите внимание на приём "%1"=="backup": кавычки добавлены с обеих сторон, чтобы сравнение не сломалось, если параметр %1 пуст. Без кавычек при пустом параметре получилась бы конструкция IF =="backup" — синтаксическая ошибка, и скрипт завершится аварийно.

Проверка существования файла перед операцией — ещё один типовой сценарий:

IF EXIST C:\CONFIG.SYS ECHO Файл CONFIG.SYS найден

IF NOT EXIST C:\CONFIG.SYS ECHO Файл отсутствует

Для проверки существования каталога в чистом DOS традиционно используют псевдоустройство NUL: IF EXIST C:\DIRNAME\NUL. Этот приём унаследован из ранних версий MS-DOS, хотя его поведение на разных версиях системы может отличаться — надёжнее проверять конкретный файл внутри каталога, если такой файл гарантированно существует.

💡

Всегда заключайте обе стороны сравнения в одинаковые кавычки: IF "%VAR%"=="значение". Это защищает скрипт от сбоев при пустых переменных и параметрах.

ERRORLEVEL: проверка кодов возврата

Конструкция IF ERRORLEVEL n означает: «если код возврата больше или равен n». Это не равенство — частая причина неверной логики скриптов. Поэтому проверки выстраивают от большего значения к меньшему:

MYPROG.EXE

IF ERRORLEVEL 2 GOTO FATAL

IF ERRORLEVEL 1 GOTO WARNING

ECHO Программа завершилась успешно

GOTO END

:WARNING

ECHO Завершено с предупреждениями

GOTO END

:FATAL

ECHO Критическая ошибка

:END

Если написать проверки в обратном порядке — сначала ERRORLEVEL 0, потом ERRORLEVEL 1, — то первая же ветка перехватит все коды, потому что любой код ≥ 0. Порядок проверок в IF ERRORLEVEL всегда идёт от максимального значения к минимальному.

⚠️ Внимание: не все программы эпохи DOS/Windows 98 корректно возвращают код завершения. Если утилита всегда возвращает 0, условие IF ERRORLEVEL будет бесполезно — проверяйте поведение конкретной программы тестовым запуском.

Организация ветвлений через GOTO и метки

Поскольку многострочных блоков нет, любая нетривиальная логика строится на метках. Метка — строка, начинающаяся с двоеточия, например :MENU. Команда GOTO MENU передаёт управление на эту строку.

Типовая структура меню выбора через параметр или команду CHOICE (входит в состав MS-DOS 6.x и доступна в среде Windows 98):

@ECHO OFF

ECHO 1 — Запустить программу

ECHO 2 — Выход

CHOICE /C:12 "Ваш выбор: "

IF ERRORLEVEL 2 GOTO EXIT

IF ERRORLEVEL 1 GOTO RUN

:RUN

CALL PROG.BAT

GOTO END

:EXIT

ECHO Завершение работы

:END

☑️ Проверка BAT-файла перед запуском в Windows 98

Выполнено: 0 / 5

Команда CALL используется для вызова другого BAT-файла с возвратом управления. Без CALL запуск второго пакетного файла завершит и текущий скрипт.

Типичные ошибки и их причины

Разберём сбои, с которыми чаще всего сталкиваются при написании условий под Windows 98.

СимптомВероятная причинаРешение
«Синтаксическая ошибка» на строке IFИспользован синтаксис CMD.EXE (IF /I, EQU, DEFINED)Переписать условие в классической форме MS-DOS
Условие срабатывает всегдаERRORLEVEL проверен от меньшего к большемуИзменить порядок проверок на убывающий
Условие не срабатывает никогдаЛишние пробелы в сравниваемых строкахУбрать пробелы вокруг ==, проверить равенство строк посимвольно
Скрипт падает при пустом параметреСравнение без кавычек: IF %1==xИспользовать IF "%1"=="x"
Русский текст условий отображается «кракозябрами»Файл сохранён в ANSI вместо OEM-кодировкиСохранить BAT в кодировке DOS (CP866)

Отдельного внимания заслуживает кодировка. COMMAND.COM работает с OEM-кодировкой (CP866), а большинство современных редакторов сохраняют текст в ANSI или UTF-8. Русские буквы в сравниваемых строках при этом превращаются в другие байты, и условие никогда не выполняется, хотя визуально строки совпадают.

📊 Где вы запускаете BAT-файлы с IF чаще всего?
На реальном ПК с Windows 98
В DOSBox или эмуляторе
В виртуальной машине
Только изучаю ретро-скрипты

Ограничения COMMAND.COM и обходные пути

Помимо отсутствия расширенного синтаксиса, у интерпретатора Windows 98 есть и другие ограничения, влияющие на условную логику:

  • ⚙️ Нет сравнения чисел — только строки и ERRORLEVEL; арифметические условия приходится эмулировать через цепочки проверок кодов возврата;
  • ⚙️ Сравнение строк всегда чувствительно к регистру, ключа /I нет;
  • ⚙️ Нет конструкции ELSE — ветка «иначе» реализуется вторым IF с NOT или переходом GOTO;
  • ⚙️ Длина строки командного интерпретатора ограничена, поэтому очень длинные условия стоит разбивать.

⚠️ Внимание: переменные окружения в DOS-сессии ограничены по объёму. Если SET-переменные «пропадают» или условия с ними ведут себя странно, возможно, переполнена область окружения — размер задаётся параметром /E: при загрузке COMMAND.COM, например в CONFIG.SYS через строку SHELL.

Если требуется сложная логика, практичный путь — вынести её во внешнюю утилиту (например, небольшую программу, возвращающую нужный ERRORLEVEL) либо использовать сторонние расширители пакетных файлов эпохи DOS. Это надёжнее, чем попытки эмулировать ветвления на чистом синтаксисе COMMAND.COM.

Как проверить версию интерпретатора

Выполните команду VER в командной строке. Windows 98 сообщит версию «Windows 98 [Version 4.10.1998]» (или 4.10.2222 для 98 SE). Среда MS-DOS внутри неё соответствует версии 7.x. Если VER показывает Windows NT/2000/XP и выше — вы в CMD.EXE, и расширенный синтаксис IF доступен.

Перенос скриптов между Windows 98 и современными системами

Скрипт, написанный в классическом синтаксисе, как правило, выполнится и в современном CMD.EXE — обратная совместимость сохранена. Обратное неверно: скрипты с IF /I, IF DEFINED, SET /A и многострочными блоками в скобках в Windows 98 работать не будут.

При переносе в сторону «старой» системы проверьте каждое условие на соответствие трём базовым формам, замените ELSE парой условий с GOTO, а сравнения без учёта регистра — явным приведением строк к одному виду или дублированием проверок для разных вариантов написания.

💡

Скрипты в классическом синтаксисе MS-DOS совместимы «вверх» с современным CMD.EXE, а современные расширения — несовместимы «вниз» с Windows 98.

Часто задаваемые вопросы

Работает ли IF /I в Windows 98?

Нет. Ключ /I (сравнение без учёта регистра) — расширение CMD.EXE из линейки Windows NT. В COMMAND.COM системы Windows 98 сравнение строк всегда чувствительно к регистру, поэтому проверяйте все возможные варианты написания отдельными условиями.

Как проверить, существует ли папка, а не файл?

Классический приём — IF EXIST C:\ИМЯ\NUL, где NUL — зарезервированное имя устройства. Однако его поведение зависит от версии системы, поэтому надёжнее проверять наличие конкретного файла внутри каталога, если такой файл гарантированно присутствует.

Почему IF ERRORLEVEL 1 срабатывает, хотя программа вернула 2?

Потому что условие означает «код возврата больше или равен указанному». Значение 2 удовлетворяет и ERRORLEVEL 1, и ERRORLEVEL 2. Проверки нужно располагать от большего значения к меньшему.

Можно ли использовать ELSE в BAT-файле Windows 98?

Нет, конструкция ELSE не поддерживается. Ветка «иначе» реализуется вторым условием с NOT или переходом GOTO на отдельную метку.

Почему русский текст в условии IF не совпадает с ожидаемым?

Наиболее вероятная причина — кодировка файла. COMMAND.COM работает с OEM-кодировкой (CP866). Сохраните BAT-файл в DOS-кодировке с помощью редактора, поддерживающего этот режим, и условие начнёт срабатывать корректно.