2012-01-23 3 views
1

В этой оболочке командного процессора NT cmd я скребут на другой день, я использую команду call для run sections of the script like functions. - Я делал много раз раньше в других сценариях. Но один из них ведет себя странно, и я не могу понять, что может быть неправильным ...Вызов внутренней «функции» в CMD-скрипте, не обновляющем переменную

Проблема в том, что при первом вызове функции она возвращает код ошибки и устанавливает глобальную переменную %RESULT%, но каждый раз, когда он вызывается снова, он не обновляет переменную с новым кодом ошибки.

Вот урезанная версия кода в вопросе:

:FACL 
REM run fileacl.exe with given OPTIONS (%1) 
REM uses global variables %TARGET% and %LOGPATH%, sets global %RESULT% 
setlocal 
set _OPTIONS_=%* 
fileacl.exe "%TARGET%" %_OPTIONS_% /SILENT >%LOGPATH%\temp.out 2>%LOGPATH%\temp.err 
set _RESULT_=%ERRORLEVEL% 
if defined DEBUG echo INSIDE FUNCTION: _RESULT_ = %_RESULT_% 
endlocal & set RESULT=%_RESULT_% & goto :EOF 

Функция вызывается в строках, как это:

call :FACL /LINE 
if defined DEBUG echo AFTER TEST #1: RESULT = %RESULT% 
... 
call :FACL /INHERIT /REPLACE /FORCE 
if defined DEBUG echo AFTER FIX #2: RESULT = %RESULT% 

Вы видите эти if defined DEBUG... линии там? Они показывают мне, что внутри функции последующие вызовы преуспевают и, таким образом, распечатывают ожидаемый %_RESULT_% 0, но глобальный %RESULT% остается неизменным. Вот пример вывода:

TEST #1: 
INSIDE FUNCTION: _RESULT_ = 107 <-- that's what I expect for the first call 
AFTER TEST #1: RESULT = 107  <-- the variable was properly set after the first call 

FIX #2: 
INSIDE FUNCTION: _RESULT_ = 0 <-- command succeeded :) 
AFTER FIX #2: RESULT = 107  <-- variable didn't change :(

RETEST: 
INSIDE FUNCTION: _RESULT_ = 0 <-- succeeded again 
AFTER RETEST: RESULT = 107  <-- still didn't change 

Вы можете спросить: что еще вы пробовали? Хорошо:

  1. Удалены setlocal\endlocal приемы и просто используется глобальная переменная %RESULT%
  2. Явное неопределенными %RESULT% и %_RESULT_% (например set RESULT=) перед каждым функция называется

... все с такие же результаты. Здесь что-то не хватает?

+1

Я использовал [этот скрипт] (http://ideone.com/eEv7N), чтобы воспроизвести что-то похожее на то, что происходит в вашем, и результаты были в отличие от ваших результатов, то есть они были разными каждый раз, как я и ожидал. Кстати, понимаете ли вы, что вы сохраняете дополнительное пространство после '% _RESULT_%' на линии 'endlocal'? Я не уверен, что это может иметь какое-то отношение к вашей нынешней проблеме, просто давая вам знать. –

+0

Хороший взгляд на дополнительное пространство! Я решил, что с помощью 'SET/A RESULT = ...', чтобы гарантировать, что сохраненное значение является числом. – ewall

ответ

4

Не уверен, потому что мы не можем видеть фактический код в контексте. Но поведение, которое вы описываете, следует ожидать, если FIX 2 CALL и ECHO находятся в скобках в скобках - возможно, как часть оператора IF или цикла FOR.

Если это так, вам необходимо использовать задержанное расширение в круглых скобках, так как весь блок анализируется до выполнения, а% RESULT% разворачивается во время разбора.

Используйте SET EnableDelayedExpansion, чтобы включить замедленное расширение, и используйте !RESULT! вместо %RESULT%, чтобы получить значение RESULT во время выполнения, а не во время разбора.

+0

dbenham, вы * точно * право: последующие вызовы «функции» находятся внутри скобок IF в скобках! Я часто использую задержанное расширение, но не думал об этом. – ewall

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