how to return a value from DOS shell function?

The following just lists what intends to be achieved (not working code):
set val1=1
set str1=test
call :getVal  %val1%  %str1%
@echo value=%val2% for %str2%
goto :eof

:getVal
set /a val2 = 2+%1
set str2="Easy %2"
goto :eof

The output is expected to be
3 for "Easy test"


jl66Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

t0t0Commented:
It works fine when I test it.

Are you using SETLOCAL somewhere in your batch file?

ALso, val2 and str2 are defined in getval. It appears you want to use val2 and str2 as global variables. The proper way to do what you are doing in your example batch file is as follows:

   @echo off
   set val1=1
   set str1=test
   call :getVal  %val1%  %str1%
   exit /b

   :getVal
   set /a val2 = %1 + 2
   set str2="Easy %2"
   echo value=%val2% for %str2%
   exit /b
0
t0t0Commented:
I guess what you're really attempting to do is pass values back from GetVal.

Defining GetVal as a sub-procedure can be likened to having two separate batch files. The problem then becomes more clearer. That is, how do we pass out values back to the perent batch file?

The way to do this is to pass them via the Environment Variable Table as in the following two batch files:.


BATCH.BAT

   @ECHO OFF
   SET Val1=1
   SET Str1=test

   SET Val2=
   SET Str2=

   CALL GetVal  %Val1%  %Str1%
   ECHO Value=%Val2% for %Str2%
   EXIT /B


GETVAL.BAT

   SET /A Val2 = %1 + 2
   SET Str2="Easy %2"
   EXIT /B


I've included 'SET Val2=' and 'SET Str2=' to reset the variables. This ensures we're not picking up spurious data.

There are other ways of passing data back to a parent batch file but this is the simplest way.
0
jl66Author Commented:
Thanks for inputs. Is there anyway not to write two batch files to achieve the same thing? If I did not setlocal, all the variables are global, right? But try to return the values from a function is difficult.
0
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Your code posted above works.

t0t0,
your examples do not make any difference, as the scope of environment variables is the whole cmd.exe process, as long as you do not use setlocal.
0
t0t0Commented:
Sure, writing two batch files was just a way of demonstrating that values can be returned via the environment table.

If you look at the following code (taken from my first comment) this should work perfectly well as a single batch file.

   @echo off
   set Val1=1
   set Str1=test
   call :GetVal  %Val1%  %Str1%
   exit /b

   :GetVal
   set /a Val2 = %1 + 2
   set Str2="Easy %2"
   echo Value=%Val2% for %Str2%
   exit /b

In some circumstances you can use setlocal however, variables are global by default and the above code should work for you if you copy and paste it straight into Notepad and save it as a batch file.

Returning a value from a function should be no more difficult than returning a value from a child batch file.
0
t0t0Commented:
Qlemo

Which is the very point I'm trying to get across to the asker. I was expecting the asker to copy and paste the code (from both examples) and report back that they didn't work - or that only the batch file making a call to a function didn't work because there's no reason why his own code shouldn't return the correct results. This would have then warranted deeper investigation.
0
jl66Author Commented:
Sorry I forgot the first line is
setlocal enabledelayedexpansion

Is this the reason I could not get the values of its functions (like GetVal) in main program? I have to put this line in. Is there anyway to write one batch script and get the value in its function?
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
The setlocal does not influence the behaviour in your code as long as you are not setting it in the GetVal. setlocal EnableDelayedExpansion sets the Delayed Expansion option, and makes all env var changes private (or local).
If you set it as first code line, it's scope is the current batch, and this works. But you can't export the var to your surrounding environment (that easy). t0t0 once showed a trick how to do it though. The code below will export val2 and str2 to be used outside the batch file.



@echo off
setlocal EnableDelayedExpansion
set val1=1
set str1=test
call :getVal  %val1%  %str1%
@echo value=%val2% for %str2%
endlocal & set val2=%val2%& set str2=%str2%
exit /b
 
:getVal
set /a val2 = 2+%1
set str2="Easy %2"
exit /b

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jl66Author Commented:
Thank all of you very much. I will verify the solutions later.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft DOS

From novice to tech pro — start learning today.