Я написал следующий пакетный скрипт, чтобы повторить путь к папке.

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 ответа2

0

Когда , if команда анализируется, синтаксический анализатор видит

echo %!prod_path!%

и здесь возникает проблема: нормальное расширение (%var%) выполняется перед отложенным расширением (!var!) поэтому этот код пытается извлечь содержимое переменной, когда имя переменной еще не определено.

Конечно, обратный синтаксис также не будет работать

echo !%prod_path%!

В этом случае имя переменной оценивается во время разбора, но во время разбора переменная все еще не имеет значения, поэтому, когда происходит отложенное расширение, имя переменной для чтения не существует.

Вам нужно расширение с двойной задержкой, то есть вам нужно что-то вроде

echo !!prod_path!!

Но это неверный синтаксис.

Итак, нам нужно использовать отложенное расширение для получения имени переменной, которую нам нужно прочитать, а затем отложенное расширение для получения значения внутри переменной.

Самое простое решение - изменить структуру кода, чтобы избежать проблемы (call subrotine, использовать goto , ...), но есть и другая альтернатива.

for %%a in (!prod_path!) do echo !%%a!

Получить имя переменной (первое отложенное расширение), сохранить полученное значение в параметре for forableable и затем прочитать значение в переменной, на которую ссылается заменяемый параметр (второе расширенное расширение)

0

Первая проблема здесь заключается в том, что не задерживаемое расширение - %…% - выполняется для всего оператора 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)
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .