2015-08-05 2 views
1

У меня есть простой скрипт, который будет считывать значение в файле version.property и выполнять определенную работу мой код находится нижеПеременная не обновляется в функции пакетного файла

TITLE StartEODMaintenance 
echo off 
cls 
set "Build=0" 

call:FindString "MAINALGO" 
IF /I "%Build%" == "MAINALGO" (
echo "start job on MainAlgo" 
) else (
    call:FindString "DRSITEALGO" 
    echo build value %Build% 
    IF /I "%Build%" == "DRSITEALGO" (
     echo "start job on secondAlgo" 
    ) else (
    echo "sth wrong"  
    ) 
) 

:FindString 
echo funtioninput %~1 
find /I /C "%~1" version.property 
if %errorlevel%==1 (
echo "errorlevel 1" 
set "Build=0" 
) 
if %errorlevel%==0 (
echo "errorlevel 0" 
set "Build=%~1" 
echo build value in function %Build% 
) 
:end 

Содержание в version.property ниже

DRSITEALGO 

проблема в том, я обнаружил, что при выполнении программы он выглядит ниже линии работы неправильно. Переменная Строить не устанавливается на значение в «% ~ 1»

set "Build=%~1" 

меня ниже, как выход

funtioninput MAINALGO 

---------- VERSION.PROPERTY: 0 
"errorlevel 1" 
funtioninput DRSITEALGO ---> the %~1 show the correct value, DRSITEALGO 

---------- VERSION.PROPERTY: 1  
"errorlevel 0" 
build value in function 0 ---> here is wrong! the Build variable somehow didn't get updated, it suppose to be DRSITEALGO 
build value 0 
"sth wrong" 

Не уверен, что я должен установить что-нибудь, чтобы сделать это работает ??

+0

Попробуйте добавить 'SETLOCAL enabledelayedexpansion' в верхней части файла –

+0

...и расширять переменные внутри циклов с помощью '!!', а не '%%'; проконсультируйтесь также [this] (http://stackoverflow.com/a/10558905/5047996) ... – aschipfl

ответ

1

The %variables% расширены, когда команда анализируется и команда if следует блок обрабатывается сразу. Поэтому, когда вы устанавливаете переменную в блоке, ее следующее использование (в echo здесь) уже было расширено, и это приводит к показу значения, которое было действительным до входа в блок!

Вам нужно delayed expansion прочитать значения переменных в момент их использования, а не проанализировать. Во-первых, выполните команду:

setlocal EnableDelayedExpansion 

Затем обратиться к переменным модифицированными ранее в том же блоке !variable!.

if %errorlevel%==0 (
echo "errorlevel 0" 
set "Build=%~1" 
echo build value in function !Build! 
) 
+0

Не похоже, что он когда-либо пытался получить значение, измененное в кодовом блоке. Я не думаю, что преждевременное расширение является проблемой. ** Редактирование: ** Ну, он выполняет 'echo build value в функции% Build%', но это приведет лишь к косметической проблеме. Это легко установить, изменив '% Build%' на '% ~ 1'. – rojo

+0

Добавление изменений! Build! внутри: FindString заставляет программу отбирать правильное значение, как насчет того, хочу ли я получить доступ к переменной Build в главном разделе, мне нужно использовать синтаксис! Build! все время? – tune

+0

@tune Нет, после выхода из блока вы можете снова использовать '% variable%'. И обратите внимание на вложенные блоки, причем самая внешняя одна должна быть закончена. Вы можете проверить это, добавив еще одну команду «echo». И, как предлагает @rojo, вы должны поместить команду 'exit/b' перед определением': FindString'. – Melebius

0

Большая проблема в том, что ваш скрипт продолжает :FindString как часть основного исполнения. В строке 6 вы call :FindString "MAINALGO", то у вас есть блок кода IF. После этого блока кода вы должны exit /b или goto :EOF или что-то, чтобы остановить выполнение основного времени выполнения, но вы этого не сделаете. Вместо этого ваш скрипт продолжает :FindString второе непреднамеренное время, устанавливает %ERRORLEVEL% на find /I /C "" version.property и продолжается до конца.

Что-то еще, что может показаться вам интересным, это conditional execution. Вместо

find /I /C "%~1" version.property 
if %errorlevel%==1 (
echo "errorlevel 1" 
set "Build=0" 
) 
if %errorlevel%==0 (
echo "errorlevel 0" 
set "Build=%~1" 
echo build value in function %Build% 
) 

... или ...

find /I "%~1" version.property 
if errorlevel 1 (
    echo "errorlevel 1" 
    set "Build=0" 
) else (
    echo "errorlevel 0" 
    set "Build=%~1" 
    echo build value in function %Build% 
) 

... вы могли бы конденсироваться ваш код немного, как это:

find /I "%~1" version.property && (
    echo "errorlevel 0" 
    set "Build=%~1" 
    echo build value in function %Build% 
) || (
    echo "errorlevel 1" 
    set "Build=0" 
) 

Я также рекомендую вам не ленитесь с отступом и форматированием. Хотя ваш код не nearly as bad as it could be, все равно будет немного легче увидеть, что происходит в :FindString, если вы отделите свои блоки кода.

Во всяком случае, посмотреть, есть ли у вас лучшая удача с этим:

TITLE StartEODMaintenance 
echo off 
cls 
set "Build=0" 

call :FindString "MAINALGO" 

IF /I "%Build%"=="MAINALGO" (
    echo "start job on MainAlgo" 
) else (
    call :FindString "DRSITEALGO" 
    echo build value %Build% 
    IF /I "%Build%"=="DRSITEALGO" (
     echo "start job on secondAlgo" 
    ) else (
     echo "sth wrong" 
     rem // exit non-zero 
     exit /b 1 
    ) 
) 

exit /b 0 
rem // end main runtime/begin script functions 

:FindString 
find /I "%~1" version.property && (
    echo "errorlevel 0" 
    set "Build=%~1" 
    echo build value in function %~1 
) || (
    echo "errorlevel 1" 
    set "Build=0" 
) 
+0

thx, вы комментируете очень цените, действительно, я очень новичок в пакетном программировании – tune

Смежные вопросы