Я пытаюсь понять, куда именно в коде возвращается GOTO :EOF?

Вот код:

SET count=1 
FOR /f "tokens=*" %%G IN (somefile.txt) DO (call :subroutine "%%G") 
GOTO :EOF

:subroutine  
echo %count%:%1  
set /a count+=1  
GOTO :EOF
51
s6398197atuser 30 Май 2016 в 02:27

4 ответа

Лучший ответ

:EOF - это предопределенный ярлык, как объясняет Microsoft в документации для команды НАЙТИ. В выводе справки при запуске в окне командной строки goto /? также объясняется этот специальный ярлык для Конец файла . Но эта предопределенная метка поддерживается только при включенных расширениях команд по умолчанию.

Вывод справки, запущенный в окне командной строки call /? и, конечно, также документация для команды CALL оба объясняют, что goto :EOF следует использовать для выхода из подпрограммы, вызываемой с помощью call :Label.

Подпрограмма - это не что иное, как другой пакетный файл, встроенный в текущий пакетный файл, вызываемый командой call. Если подпрограмма находится в конце пакетного файла, реальный конец файла отмечает конец подпрограммы.

Но в пакетном файле может быть несколько подпрограмм.

Таким образом, интерпретатору команд требуется команда для выхода из подпрограммы при достижении определенной строки в обработке команды и возврата к вызывающей командной строке. goto :EOF, а также exit /B могут использоваться везде, чтобы либо выйти из подпрограммы, либо выйти из обработки текущего пакетного файла.

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

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

Примечание 1: goto EOF без двоеточия требует, чтобы в пакетном файле действительно была строка, начинающаяся с :EOF, т. е. метка перехода EOF должна существовать в файл. goto :EOF всегда приводит к завершению подпрограммы / пакетной обработки с включенными расширениями команд, даже если в пакетном файле есть метка EOF из-за того, что строка начинается с :EOF.

Примечание 2: Команда EXIT < / a> без параметра /B всегда приводит к завершению всего командного процесса независимо от иерархии вызовов и от того, как был запущен командный процессор Windows - с параметром /K, чтобы сохранить cmd.exe работает, как используется при открытии окна командной строки, или с /C для закрытия после завершения обработки команды, как используется при двойном щелчке по командному файлу. Поэтому exit без /B следует использовать с умом в пакетном файле (лучше: никогда).

Примечание 3: exit /B не работает с отключенными расширениями команд, как показано в этом коде:

@echo off
setlocal DisableExtensions
echo Use command exit /B with command extensions disabled.
exit /B

Выполнение этого командного файла из окна командной строки приводит к выводу сообщения об ошибке:

Система не может найти указанную этикетку партии - EOF

Другими словами, exit /B без дополнительного кода выхода точно такой же, как goto :EOF и, следовательно, также зависит от расширений команд. exit без /B без кода выхода или с кодом выхода работает всегда.

Примечание 4: ERRORLEVEL не зависит от goto :EOF, но Microsoft GOTO в документации по этой теме нет. exit /B # устанавливает для ERRORLEVEL значение # как задокументировано Microsoft. exit /B # также может использоваться вместо goto :EOF для выхода из подпрограммы с определенным кодом выхода, вычисленным в командной строке, вызывающей подпрограмму, как при использовании операторов && или || или при следующей команде после вызова командной строки с помощью if errorlevel X. Однако явный выход из командного файла или подпрограммы с определенным кодом выхода обычно не требуется, поскольку ни goto :EOF, ни exit /B не изменяют текущее значение ERRORLEVEL.

Подробнее о поведении ERRORLEVEL см .:

72
Mofi 25 Июл 2018 в 15:02

: eof означает « Конец файла ». Он используется для завершения сценария без выполнения какой-либо из приведенных ниже команд.

2
Micho 29 Май 2016 в 23:39

GOTO :EOF функционально эквивалентен exit /B, но обе формы работают только при включенных расширениях. Проверка на этот момент очень проста:

setlocal DisableExtensions
goto :EOF

Сравните предыдущий код с этим:

setlocal DisableExtensions
exit /B

Это означает, что GOTO :EOF возвращается в ту же точку , где должен был вернуться exit /B.

8
Aacini 30 Май 2016 в 01:06

Поскольку GOTO и CALL используют одни и те же функции для поиска ярлыка, у вас также есть возможность получить доступ к :EOF с помощью CALL:

CALL ::EOF

То же, что и GOTO (когда CALL с дополнительной точкой с запятой) фактический конец файла будет предпочтительной точкой, в которую будет идти поток скрипта. Если у вас есть собственная метка \ функция, определенная с помощью EOF , вы можете получить к ней доступ с помощью одной точки с запятой.

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

0
npocmaka 12 Ноя 2020 в 11:51