2017-02-21 2 views
1

Попытка установить простой скрипт сборки, который расширит путь на основе других переменных среды. Этот небольшой скрипт работает отлично:Windows cmd shell: if-then-else weirdness для операторов блока

echo off 
call c:\vstudio\vc\bin\vcvars32.bat 
set _ISGIT=1 
echo current path is %PATH% 
if defined _ISGIT set PATH=c:\git\bin;%PATH% 

Но если я хочу сделать выполнить несколько строк, основанные на существовании переменной _ISGIT, то я думал, что это будет работать

echo off 
call c:\vstudio\vc\bin\vcvars32.bat 
set _ISGIT=1 
echo current path is %PATH% 
if defined _ISGIT (
    set PATH=c:\git\bin;%PATH% 
    set PATH=c:\foo;%PATH% 
) 

Но что дает следующий результат :

D:\>test.cmd 

D:\>echo off 
current path is C:\vstudio\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\MSBuild\14.0\bin;C:\ 
vstudio\Common7\IDE\;C:\vstudio\VC\BIN;C:\vstudio\Common7\Tools;C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319;C:\vstudio 
\VC\VCPackages;C:\Program Files (x86)\HTML Help Workshop;C:\vstudio\Team Tools\Performance Tools;C:\Program Files (x86)\ 
Windows Kits\10\bin\x86;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\;C:\ProgramData\Oracl 
e\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\U 
sers\jselbie\.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files (x86)\Windows Kits\10\Windows Performance To 
olkit\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\nodejs\;C:\Program Files (x86)\Skype\Phone\;C:\WINDOWS\s 
ystem32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Co 
rporation\PhysX\Common;C:\Users\jselbie\.dnx\bin;C:\Users\jselbie\AppData\Roaming\npm;%USERPROFILE%\AppData\Local\Micros 
oft\WindowsApps; 

MSBuild\14.0\bin was unexpected at this time. 

MSBuild\14.0\bin was unexpected, вероятно, побочный эффект от первоначального пути, содержащего каталог с пробелом. Наличие пробела в расширенной команде с (), похоже, отключает скрипт.

Как мне обойти это без необходимости иметь независимые заявления if defined?

ответ

1
set "PATH=c:\git\bin;%PATH%" 
set "PATH=c:\foo;%PATH%" 

с использованием цитат делает cmd интерпретировать цитируемое-строку как один знак, поэтому он не видит ) внутри переменной [т.е. путь], которая закрывает if defined ... (

3

Есть две вещи неправы. Во-первых, одна из каталогов в пути содержит круглые скобки. Перед разбором выполняется расширение переменной, поэтому закрывающая скобка из PATH принимается за закрытие круглой скобки блока IF. Чтобы исправить это, вам нужно поставить свое назначение в кавычки: set "PATH=...".

Во-вторых, внутри блока (обозначается круглыми скобками) все переменные среды во всем блоке сначала расширяются сразу. Затем блок анализируется. Это означает, что расширенный путь во второй строке такой же, как и на первой строке. Он не изменяется в первой строке. Чтобы исправить это, вы должны либо изменить путь полностью в одной строке:

if defined _ISGIT (
    set "PATH=c:\foo;c:\git\bin;%PATH%" 
) 

или использовать замедленное расширение:

setlocal enabledelayedexpansion 
if defined _ISGIT (
    set "PATH=c:\git\bin;!PATH!" 
    set "PATH=c:\foo;!PATH!" 
) 

Delayed expansion работы путем расширения переменной на более позднем этапе, то есть после того, как переменная имеет была назначена первой строкой. Он должен быть включен с помощью команды setlocal, прежде чем ее можно будет использовать.

+0

Однолинейным решение не работает - он должен быть «установлен» PATH = ... «' 'не' set PATH = "..." ' – selbie

+0

вещь' enabledelayedexpansion' вообще не работает .. все еще пытается ... – selbie

+0

@selbie благодарит за комментарий о кавычках. Это была опечатка, которую я сейчас исправил. Я не уверен, что отсроченное расширение не работает. Также потребовались исправления кавычек, может быть, это так? –

1

Вклад в почти исчерпывающий Klitos Kyriacou's answer.

Существует implicit endlocal command at the end of a batch file.

Следовательно, ваш test.cmd должен быть следующими (читайте ENDLOCAL):

@echo off 
call c:\vstudio\vc\bin\vcvars32.bat 
set _ISGIT=1 
echo current path is %PATH% 
setlocal enabledelayedexpansion 
if defined _ISGIT (
    set "PATH=c:\git\bin;!PATH!" 
    set "PATH=c:\foo;!PATH!" 
) 
endlocal&(
    set "PATH=%PATH%" 
) 

или следующим образом (читайте CALL, примечание удвоилось знаки процента):

@echo off 
call c:\vstudio\vc\bin\vcvars32.bat 
set _ISGIT=1 
echo current path is %PATH% 
if defined _ISGIT (
    call set "PATH=c:\git\bin;%%PATH%%" 
    call set "PATH=c:\foo;%%PATH%%" 
) 
Смежные вопросы