Ответ 1
Что, поскольку блок() анализируется только один раз, он заменяет% TMPFILE% до того, как он запустит ваш цикл.
У меня есть пакетный файл, который инициализирует переменные через SET внутри цикла for, для набора файлов на диске:
for %%f in (%MYTARGETDIR%\*config.xml) do (
SET TMPFILE=%%F.tmp
echo In loop %TMPFILE%
)
echo End loop %TMPFILE%
когда я запускаю его в совершенно новой командной оболочке (без определения TMPFILE), эхо-цикл In пуст, но эхо-конец контура не является.
Когда я запускаю второй раз, его уже установлен и выводит его значение, игнорируя набор до тех пор, пока цикл не закроется.
Идеи, почему это так, и каково обходное решение?
Что, поскольку блок() анализируется только один раз, он заменяет% TMPFILE% до того, как он запустит ваш цикл.
Для записи скорректированный script выглядит следующим образом:
setlocal ENABLEDELAYEDEXPANSION
for %%f in (%MYTARGETDIR%\*config.xml) do (
SET TMPFILE=%%F.tmp
echo In loop !TMPFILE!
)
echo End loop %TMPFILE%
Спасибо, Крис за вашу помощь.
Это потому, что переменные среды заменяются при чтении команды. Для следующей команды:
for %%f in (%mytargetdir%\*config.xml) do (
set tmpfile=%%f.tmp
echo In loop %tmpfile%
)
вся команда (от for
до закрывающейся скобки) считывается и заменяется перед выполнением.
Вам нужно использовать задержанное расширение, например:
@echo off
setlocal enableextensions enabledelayedexpansion
set full=/u01/users/pax
:loop1
if not "!full:~-1!" == "/" (
set full2=!full:~-1!!full2!
set full=!full:~,-1!
goto :loop1
)
echo !full!
endlocal
Когда вы включаете замедленное расширение, маркеры "%"
по-прежнему действуют по-прежнему, но вы можете использовать маркеры "!"
для выполнения замедленного расширения.
Вы также можете использовать CALL SET вместо задержанного расширения.
Обычно я вызываю CMD.EXE с параметрами /e: on и /v: on для включения расширений команд и расширения с задержкой переменных. Затем любые исполняемые скрипты, которые я использую, кодируются, чтобы проверить, включено ли замедленное расширение переменной.
Это первый раз, когда я услышал, что SETLOCAL принимает аргументы. Я проверил с SETLOCAL/? и конечно же! Для меня это время и код.
Однако я заметил, что расширения команд должны быть включены в CMD.EXE, прежде чем SETLOCAL будет распознавать параметр ENABLEDELAYEDEXPANSION. Это результат вывода SETLOCAL/?
If Command Extensions are enabled SETLOCAL changes as follows:
SETLOCAL batch command now accepts optional arguments:
ENABLEEXTENSIONS / DISABLEEXTENSIONS
enable or disable command processor extensions. These
arguments takes precedence over the CMD /E:ON or /E:OFF
switches. See CMD /? for details.
ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION
enable or disable delayed environment variable
expansion. These arguments takes precedence over the CMD
/V:ON or /V:OFF switches. See CMD /? for details.
Спасибо вам за этот ценный ответ.