2017-02-21 6 views
3

При запуске следующего командного файла я ожидаю, что программа вернется из подпрограммы func и отобразит сообщение «end program». Вместо этого программа, кажется, зависает при нажатии клавиши после того, как команда pause выполняется в цикле for. Замена выход/b с переключение: eof, похоже, имеет такой же эффект.Невозможно вернуться из бесконечного цикла внутри процедуры

@echo off 

echo start program 
call :func 
echo end program 
pause 
exit /b 

:func 
echo start func 
for /l %%l in() do (
    echo start loop 
    pause 
    exit /b 
    echo end loop 
) 
echo end func 
exit /b 

Ожидаемые результаты:

start program 
start func 
start loop 
Press any key to continue... 
end program 
Press any key to continue... 

Я хотел бы избежать использования Гота метки в виде бесконечной петли. При следующем цикле, сообщение итерации отображается только один раз:

:test 
for /l %%l in (1,1,3) do (
    echo iteration: %%l 
    exit /b 
) 
exit /b 

Что бы надлежащим образом использовать бесконечный цикл внутри подпрограммы и все еще быть в состоянии вернуться к абоненту?

+0

Я не уверен, что я следую, термин бесконечный является конкретным, если он непрерывный, как он может вернуться? – Compo

+0

@Compo: «exit/b» - это * предполагается *, чтобы закончить цикл, но, похоже, не работает с циклами '/ L' – abelenky

+2

. Идея состоит в том, чтобы вернуться из вызова функции внутри цикла for, когда конкретное условие встретил. В сценариях пакетного файла вы не можете влиять на условие цикла for из своего тела. Я также обнаружил, что нет прямого пути выхода из бесконечного цикла, избегая использования goto-label. Дополнительную информацию см. В следующем разделе DosTips: http://www.dostips.com/forum/viewtopic.php?f=3&t=2707 – treintje

ответ

2

В ответе # 7 в теме DosTips вы можете прочитать эту фразу: «Невозможно разбить цикл FOR/L в том же контексте CMD, поэтому я использовал трюк для экспорта цикла в новый CMD, который может быть поврежден с помощью команды EXIT, а выполнение возвращается к коду вызывающего абонента «. То есть:

@echo off 
if "%~1" neq "" goto %1 

echo start program 
cmd /C "%~F0" :func 
echo end program 
pause 
exit /b 

:func 
echo start func 
for /l %%l in() do (
    echo start loop 
    pause 
    exit 
    echo end loop 
) 
echo end func 
exit /b 

Вы можете прочитать более подробное описание этой точки на The ultimate while loop DosTips тему.