Как вернуть значение из одного пакетного файла в пакетный файл вызывающего

У меня есть общий .bat файл, который читает файл status.xml и узнает значение поля состояния. Этот командный файл затем вызывается другими командами для определения значения состояния. вызывающие пакетные файлы отправляют имя файла в общий файл bat. Я не могу отправить статус из общего пакетного файла в вызывающие пакетные файлы. Кто-нибудь может помочь?

main batch file
-- will call the common bat file and send the file name and a variable as arguments
setlocal
call Common.bat c:\folderdir\files\status.xml val1
-- trying to print the status returned by the common bat file
echo [%val1%]

common batch file
@ECHO off
setlocal EnableDelayedExpansion

rem will loop through the file and read the value of the status tag
(for /F "delims=" %%a in (%1) do (
set "line=%%a"
set "newLine=!line:<Interface_status>=!"
set "newLine=!newLine:</Interface_status>=!"
if "!newLine!" neq "!line!" (
  @echo Status is !newLine!
rem I want to send`enter code here` the value of newLine to the calling batch file
  set %~2 = !newLine!   <--this does not work
)

)) 

Ответ 1

В скобке SETLOCAL/ENDLOCAL (где EOF = ENDLOCAL) любые изменения, внесенные в среду, отменены.

Вам нужно установить переменную в Common.bat, которая будет видна после последней закрывающей скобки (т.е. вашего возвращаемого значения), и это может быть пустая строка.

Затем в строке после Common.bat окончательной закрывающей скобки поместите эту строку:

ENDLOCAL&set %~2=%returnvalue%

где returnvalue содержит er, значение, которое вы хотите вернуть (смешно, что...)

BTW: Строка SET является SPACE-SENSITIVE. Если бы работала строка, вы бы установили переменную "VAR1 " - not "VAR1" - пробел перед = был бы ВКЛЮЧЕН в имя переменной - и любые пробелы после =, также включенные в значение назначен.

Синтаксис

set "var=value"

часто используется, чтобы исключить любые пробелы с пробелами в строке (как могут оставлять некоторые редакторы)


(Вздох)...

@ECHO off
setlocal EnableDelayedExpansion

rem will loop through the file and read the value of the status tag
(for /F "delims=" %%a in (%1) do (
set "line=%%a"
set "newLine=!line:<Interface_status>=!"
set "newLine=!newLine:</Interface_status>=!"
if "!newLine!" neq "!line!" (
  @echo Status is !newLine!
rem SET THE RETURN VALUE
  set RETURNVALUE=!newLine!
)

)) 

ENDLOCAL&SET %~2=%RETURNVALUE%

Ответ 2

Питер Райт описывает основную технику.

Последняя проблема заключается в выходе из цикла for без потери значения.

Вы можете использовать GOTO :break, поскольку GOTO немедленно останавливает все циклы.

Невозможно использовать !newline! в блоке ENDLOCAL, поскольку он будет расширяться после ENDLOCAL, но затем он будет пустым.

@ECHO off
setlocal EnableDelayedExpansion

for /F "delims=" %%a in (%1) do (
  set "line=%%a"
  set "newLine=!line:<Interface_status>=!"
  set "newLine=!newLine:</Interface_status>=!"
  if "!newLine!" neq "!line!" (
    @echo Status is !newLine!
    goto :break
  )
)

( 
  endlocal
  set "%~2=%newLine%"
)

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

for /F "delims=" %%a in ("!newline!") DO (
  endlocal
  set "%~2=%%~a" 
)