Ожидаемый ввод: Начало = 1, Конец = 500, Интервал = 100
Ожидаемый результат:
1, 100
101, 200
201, 300
301, 400
401, 500
@echo off
set start=1
set end=500
set interval=100
for /L %%g in (%start%, %interval%, %end%) do (
set first=%%g
set /a last=%first% -1 + %interval%
echo %first% , %last%
)
Фактический выход:
401, 401 -1 + 100
401, 401 -1 + 100
401, 401 -1 + 100
401, 401 -1 + 100
401, 401 -1 + 100
Не уверен, почему first присваивается значение 401, оцените любую помощь
Это классическая проблема отложенного расширения. Тип help set
или set /?
из командной строки для обсуждения отложенного расширения (чуть позже половины полной справки).
Нормальное расширение с использованием %var%
происходит при разборе строки. Проблема в том, что весь ваш блок цикла FOR анализируется за один проход. Итак, вы видите постоянное значение, существовавшее до запуска цикла. Значение 401, вероятно, осталось от предыдущего запуска.
Решение - отложенное расширение. Сначала вы должны включить его, используя setlocal enableDelayedExpansion
. Затем вы используете !var!
вместо того %var%
. Это даст значение во время выполнения, а не во время синтаксического анализа.
Кроме того, нет необходимости расширять числовые переменные при использовании set /a
.
@echo off
setlocal enableDelayedExpansion
set start=1
set end=500
set interval=100
for /L %%g in (%start%, %interval%, %end%) do (
set /a first=%%g, last=first-1+interval
echo !first!, !last!
)
@dbenham прав. Выброшу альтернативу. Я нахожу отложенное расширение немного уродливым и сбивающим с толку для более длинных подпрограмм, поэтому я, как правило, буду в одиночестве call
как "тело" for
петля. Внутри call
расширение переменной происходит "нормально". Обратите внимание:
@echo off
setlocal
set start=1
set end=500
set interval=100
for /L %%g in (%start%, %interval%, %end%) do call :_d %%g
endlocal
goto :EOF
:_d
set /a last=%1 - 1 + interval
echo %1, %last%
В данном конкретном случае это, конечно, больше кода, но для менее тривиальных командных файлов я думаю, что это «победа».
Кстати: у вас нет setlocal
/ endlocal
там, поэтому значения для first
и last
будет сохраняться при выполнении, если вы продолжаете запускать их в одной оболочке, и давать разные результаты при втором запуске кода. Я обычно помещаю свои командные файлы в setlocal
/ endlocal
пара для предотвращения «утечки» переменных, которые я использую в сценарии, в среду родительской оболочки.
Наконец, я повторю то, что говорит @VasiliSyrakis: если вы можете избежать использования cmd.exe
тогда, во что бы то ни стало, избегайте этого. Я обычно пишу много вещей партиями, но, по общему признанию, это немного похоже на забивание гвоздей с помощью отвертки. много проблем.