Мне нужно установить некоторые переменные на основе аргумента для пакетного сценария Windows.
@echo off
if [%1]==[] (
echo "Usage: xxx <AAA|ZZZ>"
) else (
if [%1]==[AAA] (
SET SOURCE_DIR=c:\dirA
) else if [%1]==[ZZZ] (
SET SOURCE_DIR=c:\dirZ
)
echo Source dir is: %SOURCE_DIR%
)
Когда я вызываю приведенный выше сценарий с параметром AAA, Я получаю вывод
Source dir is: c:\dirA
после второго звонка. С тех пор, когда я чередую AAA и ZZZ, Я получаю этот узор:
C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA
C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA
Похоже, я манипулирую глобальной переменной, доступной даже после завершения скрипта. Одно это меня не беспокоит, но новая настройка доступна только после завершение сценария - это проблема, так как остальная часть моего сценария зависит от этого (очевидно).
Как правильно использовать локальные переменные в этом контексте? Как объяснить странное поведение вышеупомянутой «установки отложенного состояния»?
Спасибо!
Переменные в пакетном файле по умолчанию раскрываются в начале выполнения скрипта; вам нужно использовать отложенное расширение, которое доступно с "!" разделитель:
echo Source dir is: !SOURCE_DIR!
Это работает, только если для интерпретатора команд включено отложенное раскрытие, которое по умолчанию не; поэтому вам нужно включить его при запуске интерпретатора, используя CMD.EXE /V
.
Вы также можете включить его, используя этот оператор в своем командном файле:
setlocal ENABLEDELAYEDEXPANSION
Больше информации Вот.
Я мог бы справиться с этим немного проще ...
@ECHO OFF
SET SOURCE_DIR=
IF /I [%1]==[AAA] SET SOURCE_DIR=c:\dirA
IF /I [%1]==[ZZZ] SET SOURCE_DIR=c:\dirZ
IF [%SOURCE_DIR]==[] (
ECHO "Usage: xxx <AAA|ZZZ>"
EXIT 1
)
ECHO Source dir is: %SOURCE_DIR%
Должен признаться, я немного сбит с толку, почему это работает, когда пример в вопросе - нет. Я предполагаю, что это проблема определения объема работ. Поскольку в этом примере переменная SOURCE_DIR была установлена в скобках, ее значение в корневой области остается неизменным. Мой сценарий изменяет SOURCE_DIR в корневой области.
Что касается того, почему трюк с отложенным расширением заставляет его улавливать изменение, которое было сделано на более глубокий уровень, похоже, что расширение происходит в начале каждого изменения объема. Таким образом, откладывая, вы в основном заставляете его снова расширяться после возврата в корневую область.