Не получая ожидаемый результат при отражении
Я написал следующий пакетный скрипт, чтобы повторить путь к папке.
set TW_prod_cer_path=D:\prod_path
set /p client="Enter client: "
if %client% equ TW (
setlocal enabledelayedexpansion
set prod_path=!client!_prod_cer_path
echo !prod_path!
echo %!prod_path!%
)
И я получаю вывод ниже
Enter client: TW
TW_prod_cer_path
ECHO is off.
Но мой ожидаемый результат:
Enter client: TW
TW_prod_cer_path
D:\prod_path
Может ли кто-нибудь объяснить причину этого, а также корректирующие действия, которые необходимо предпринять, чтобы получить ожидаемый результат?
2 ответа
Когда if
команда разбирается, парсер видит
echo %!prod_path!%
и тут возникает проблема: нормальное расширение (%var%
) выполняется перед отложенным расширением (!var!
) поэтому этот код пытается получить содержимое переменной, когда имя переменной все еще не определено.
Конечно, обратный синтаксис также не будет работать
echo !%prod_path%!
В этом случае имя переменной оценивается во время разбора, но во время разбора переменная все еще не имеет значения, поэтому, когда происходит отложенное расширение, имя переменной для чтения не существует.
Вам нужно расширение с двойной задержкой, то есть вам нужно что-то вроде
echo !!prod_path!!
Но это неверный синтаксис.
Итак, нам нужно использовать отложенное расширение для получения имени переменной, которую нам нужно прочитать, а затем отложенное расширение для получения значения внутри переменной.
Самое простое решение - изменить структуру кода, чтобы избежать проблемы (call
субротин, используйте goto
, ...), но есть и другая альтернатива.
for %%a in (!prod_path!) do echo !%%a!
Получить имя переменной (первое отложенное расширение), сохранить полученное значение внутри for
замещаемый параметр, а затем считывает значение в переменной, на которую ссылается заменяемый параметр (второе отложенное расширение)
Первая проблема здесь заключается в том, что не задерживающееся расширение - %…%
- сделано для всего if
заявление, включая весь блок в скобках. (Это хитрость синтаксического анализатора; cmd по-прежнему считает все это одной командной строкой.)
Другими словами, %…%
Расширения здесь происходят до set
команда достигнута, несмотря на то, что она выше.
Вторая проблема заключается в том, что вы неправильно упорядочили отложенное / не отложенное расширение. Если вы хотите "разыменовать" переменную, вам потребуется расширить ее имя не позже, а раньше; например
set foo=value
set bar=foo
echo !%bar%!
Рассматривали ли вы другой язык программирования, например PowerShell? У него есть хеш-таблицы:
$prod_paths = @{
"TW" = "D:\prod_path";
}
$client = Read-Host -Prompt "Enter client"
if ($client -ceq "TW") {
echo $prod_paths.Item($client)
}