Вопрос или проблема
ПРОБЛЕМА
Командная строка (cmd.exe) не может найти внутренние команды FOR
или IF
, когда имя команды вызывается через переменную внутри команды FOR
.
Пример команды
for /f %a in ("FOR") do %a /? :: Ошибка :: 'FOR' не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл.
Дополнительные детали
• В примерной команде происходит попытка выполнить команду FOR /?
внутри команды FOR
с использованием переменной для ее вызова.
• Проблема возникает, когда любая команда FOR
или любая команда IF
вызываются через переменную внутри команды команды FOR
.
• Не имеет значения, является ли переменная переменной команды FOR
(например, %a
) или обычной переменной (например, !var!
).
• Если команда вызывается без использования переменной, команда успешно выполняется внутри команды FOR
.
УСТРАНЕНИЕ НЕИСПРАВНОСТЕЙ
• Я попытался выполнить команду в пакетном файле. Я заменил переменную FOR
%%a
на %a
в пакетном файле и получил ту же ошибку.
• Если переменная установлена внутри команды цикла FOR
, она не выполняет команду FOR
с тем же сообщением об ошибке.
for /f %a in ("AnyString") do set x=for /?&!x!
• Если переменная установлена до команды FOR
, и переменная вызывается без задержанной expansión, команда выполняется успешно.
set x=for /?
for /f %a in ("AnyString") do set x=for /?&%x%
• Следующая команда демонстрирует, что для команд, найденных в команде
HELP
, эта проблема касается только командFOR
иIF
. КомандаGRAFTABL
также выдаст ошибку, но эта команда была удалена из cmd.exe много лет назад.>echo off&for /f %a in ('help^|findstr /R /C:"^.[ABCDEFGHIJLKMNOPQRSTUVWXYZ]"') do %a /?>nul Доступ запрещен. 'FOR' не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл. 'GRAFTABL' не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл. 'IF' не распознается как внутренняя или внешняя команда, исполняемая программа или пакетный файл.
РЕШЕНИЕ
Если вы предваряете команду cmd /c
, чтобы выполнить ее в новом процессе, это будет работать с переменными.
for /f %a in ("FOR") do cmd /c %a /?
Некоторые моменты, которые стоит учитывать:
- Определение переменной без использования
set "_var=Strings"
и дополнительных команд не рекомендуется, поэтому попробуйте использовать это и посмотрите результат.
set "x=for /?"
for /f %a in ("AnyString") do set "x=for /?"& call %%x%%
- Для считывания значения или выполнения переменной в той же строке, где вы ее определили, я предлагаю попробовать
call %% _var %%
set "_variable=SomeValue" & call %%_variable%%.
- Ваш код будет перечислять и выполнять файлы в порядке алфавита, и в какой-то момент он запустит
DiskPart.exe
. В этот момент циклfor
не будет работать как ожидалось, и поэтому вы видите сообщение об ошибке.
- Вы можете избежать этого, используя
if not /i "%~a" == "DiskPart.exe" "%~a" /?
.
- Как только
Diskpart.exe
запускается, все, что следует за ним в вашем цикле, не будет обработано, потому что эти команды не существуют в [ консоль:DiskPart>_
]DiskPart
.
- Пока вы не наберете
exit
, команды в цикле “for” не будут применяться к
DiskPart
, потому что открывается новое окно, и вы нажали “[да]”, чтобы запустить с правами администратора, поэтому не делайте это сDiskPart.exe
, так как ваш
скрипт не предназначен для модификации дисков/разделов… по крайней мере, я так предполагаю.
- Это объясняет, почему у вас есть поведение, функционирующее в:
for /f %a in ("FOR") do cmd /c %a /?
- Если вы ищете более полную помощь по внутренним и внешним командам, я рекомендую использовать скрипт allhelp.bat, доступный на страницах скриптов Rob van der Woude. Этот скрипт вернет каждую команду вместе с ее соответствующим текстом справки в хорошо структурированном формате HTML. Однако учтите, что в какой-то момент вам может понадобиться ответить [НЕТ] на исполняемые команды, такие как
RegEdit
иDiskPart
.
- В конце сгенерированной HTML-страницы вы найдете кредитные данные:
Этот HTML-файл был сгенерирован: AllHelp.bat, версия 1.40 для Windows NT 4 / 2000 / XP Написано Робом ван дер Вуде http://www.robvanderwoude.com
- Не беспокойтесь о том, что он предназначен для старых версий Windows; хотя вы можете столкнуться с некоторыми сообщениями об ошибках, они не повлияют на функциональность вашей системы или полученный HTML.
Примечание 1: Для RegEdit
, DiskPart
и других команд, которые будут перечислены с помощью help /?
нет аргумента /?
.
Примечание 2: Когда вы видите сообщение: “Доступ запрещен
“, это означает, что некоторые перечисленные команды (независимо от того, являются ли они эксклюзивными для консоли или нет) требуют административных учетных данных для выполнения в активном окне, где они были вызваны (текущем окне командной строки). Если эти учетные данные не предоставлены, вы получите это сообщение.
Ответ или решение
Проблема с внутренними командами FOR
и IF
в командной строке Windows
В командной строке Windows (cmd.exe) пользователи иногда сталкиваются с проблемами при попытке вызвать внутренние команды, такие как FOR
и IF
, через переменные в контексте цикла FOR
. Данная проблема, как правило, провоцирует сообщение об ошибке о том, что команда не распознана. В этом ответе мы разберем данную проблему, проанализируем причины её возникновения и предложим возможные обходные пути.
Суть проблемы
При вызове команды FOR
или IF
через переменные, особенно внутри цикла FOR
, cmd.exe не может распознать команду. Рассмотрим пример:
for /f %a in ("FOR") do %a /?
При выполнении данной команды вы получите сообщение об ошибке:
'FOR' не является внутренней или внешней командой, исполняемым приложением или пакетным файлом.
Анализ проблемы:
-
Переменные и обработка: Команды
FOR
иIF
являются встроенными командами в командной строке и, как результат, их обработка происходит в контексте самого cmd.exe. При попытке вызвать их через переменные происходит потеря контекста, что и приводит к ошибке. -
Использование командных переменных: При определении переменных с помощью
SET
и последующем их вызове с использованием специфической синтаксической конструкции (например, с использованием!var!
для отложенной подстановки), также может возникать ошибка, если контекст не сохраняется правильно.
Устранение неполадок
При отладке этой проблемы важно учитывать следующие моменты:
- Замените переменные типа
%a
на%%a
, если вы выполняете команду из пакетного файла. - Убедитесь, что команда, которую вы вызываете через переменную, правильно формируется до момента её выполнения.
Обходные пути
Существует несколько способов избежать данной проблемы:
-
Использование
cmd /c
: Вы можете запустить внутреннюю команду в новом процессе, что позволит обойти ограничение идентификации команды внутри текущего контекста:for /f %a in ("FOR") do cmd /c %a /?
-
Работа с
CALL
: Использование командыCALL
для вызова переменной также может помочь избежать проблемы:set "x=for /?" for /f %a in ("AnyString") do call %x%
-
Создайте переменные заранее: Если переменные инициализируются до выполнения цикла
FOR
, это также способствует корректной работе:set "x=for /?" for /f %a in ("AnyString") do set x=for /? & %x%
Заключение
Команды FOR
и IF
имеют специфическое поведение в контексте сценариев командной строки в Windows, что может создавать трудности при их вызове через переменные. Понимание механизма работы интерпретатора команд поможет избежать ошибок, связанных с их использованием. Использование обходных путей, таких как вызов через cmd /c
или использование CALL
, позволит вам эффективно управлять командами и получать необходимые результаты.
Для сопровождения вашей работы рекомендуется всегда держать в поле зрения документацию Windows и руководства по командной строке, чтобы быть в курсе всех нюансов и избегать распространенных ошибок.