Как да върна стойност от един пакетен файл към пакетен файл на извикващия

Имам общ .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
)

)) 

person user2593173    schedule 19.07.2013    source източник


Отговори (2)


В рамките на SETLOCAL/ENDLOCAL скоба (където EOF=ENDLOCAL) ВСИЧКИ промени, направени в средата, се отменят.

Трябва да зададете променлива в рамките на Common.bat, която да се вижда след последната затваряща скоба (т.е. вашата върната стойност - и може да е празен низ.

След това, в реда след последната затваряща скоба на common.bat, поставете този ред:

ENDLOCAL&set %~2=%returnvalue%

където returnvalue съдържа er, стойността, която искате да върнете (смешно, че...)

BTW: Низ SET е ЧУВСТВИТЕЛЕН КЪМ ИНТЕРВАЛ. Ако редът работеше, щяхте да задавате променливата "VAR1 " - не "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%
person Magoo    schedule 19.07.2013
comment
Благодаря за информацията! Проблемът е, че не мога да задам върнатата стойност, съдържаща се в !newLine! към всяка друга променлива. така че не мога да задам нов ред да returnvalue и да го използвам след блока - person user2593173; 19.07.2013
comment
Благодаря! Имах няколко реда код след for цикъла, който не се изпълняваше по някаква причина и затова върнатата стойност не беше зададена. - person user2593173; 19.07.2013
comment
За мен ENDLOCAL и & трябваше да бъдат разделени като ENDLOCAL & set returnvalue=%returnvalue%, re: ss64.org/viewtopic .php?pid=4940#p4940 -- Не знам дали това е печатна грешка в дадения отговор тук. - person Alex Hall; 10.06.2016
comment
@AlexHall : Поне на теория допълнителните интервали не са задължителни. Никога не съм попадал в ситуация, в която трябваше да ги използвам. Може би, ако разширите малко вашите наблюдения, всички ние може да разчитаме на нещо. - person Magoo; 10.06.2016
comment
Не съм сигурен какво направи разликата ENDLOCAL& да не работи за мен и ENDLOCAL & да работи. Скриптът, в който се случи това, се изпълняваше от конзола; с %returnvalue%, зададен преди това чрез напр. команда SET returnvalue=thisString. Когато стартирах скрипта от нови конзоли, ENDLOCAL& set returnvalue=%returnvalue% нямаше да доведе до %returnvalue% с присвоена стойност (с други думи не съществуваше) в конзолата; докато ENDLOCAL & set returnvalue=%returnvalue% завърши с присвояване на стойност. Освен това това беше на Windows 7. - person Alex Hall; 19.06.2016
comment
@AlexHall е мистерия. Може би бихте могли да публикувате използвания код на обществено място, за да може да бъде проучен отблизо. - person Magoo; 20.06.2016

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

Последният проблем изглежда е да се излезе от 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" 
)
person jeb    schedule 19.07.2013
comment
Мога да предам стойността от common.bat към main.bat. Имам въпрос обаче. Ако дадено приложение извика main.bat, тогава ще може ли да извлече стойността от main.bat? - person user2593173; 19.07.2013
comment
Вашето приложение също ли е команден файл? Тогава това е начинът, по който Питър и аз показахме. В противен случай можете да опитате да повторите резултата и приложението да филтрира stdin потока - person jeb; 20.07.2013