Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch file for loop through switch-like arguments?

I'm trying to loop through the arguments that I am passing to a batch file. Based on the argument, I want to set a variable flag true or false for use later in the script

So my command is "myscript.bat /u /p /s"

And my code is:

FOR /f %%a IN ("%*") DO (
  IF /I "%%a"=="/u" SET UPDATE=Y
  IF /I "%%a"=="/p" SET PRIMARY=Y
  IF /I "%%a"=="/s" SET SECONDARY=Y
)

It only works if i have a single argument, which tells me that it is getting the entire list of arguments as a single argument. I've tried "delims= " but to no avail. Any thoughts on getting each spaced argument?


What about adding a value to one of the params?

myscript.bat /u /p /d TEST /s

:loop
IF "%~1"=="" GOTO cont
IF /I "%~1"=="/u" SET UPDATE=Y
IF /I "%~1"=="/p" SET PRIMARY=Y
IF /I "%~1"=="/s" SET SECONDARY=Y
IF /I "%~1"=="/d" SHIFT & SET DISTRO="%~1"
SHIFT & GOTO loop

:cont

But the SHIFT that comes inline with the last IF doesn't actually shift anything. DISTRO ends up being "/d" instead of "TEST"

like image 682
DssTrainer Avatar asked Mar 09 '11 14:03

DssTrainer


People also ask

Can a batch file take arguments?

Batch scripts support the concept of command line arguments wherein arguments can be passed to the batch file when invoked. The arguments can be called from the batch files through the variables %1, %2, %3, and so on.

How do I run an argument from a batch file?

In the batch script, you can get the value of any argument using a % followed by its numerical position on the command line. The first item passed is always %1 the second item is always %2 and so on. If you require all arguments, then you can simply use %* in a batch script.

What is for f in batch file?

FOR /F processing of a command consists of reading the output from the command one line at a time and then breaking the line up into individual items of data or 'tokens'. The DO command is then executed with the parameter(s) set to the token(s) found.

What does tokens mean in batch file?

FOR /F processing of a text file consists of reading the file, one line of text at a time and then breaking the line up into individual items of data called 'tokens'. The DO command is then executed with the parameter(s) set to the token(s) found.


2 Answers

You're not too far off on your original piece, and since I dislike GOTO loops, I thought I'd post this:

FOR %%a IN (%*) DO (
  IF /I "%%a"=="/u" SET UPDATE=Y
  IF /I "%%a"=="/p" SET PRIMARY=Y
  IF /I "%%a"=="/s" SET SECONDARY=Y
)

The reason it was only working with one parameter is the over-use of quotes. By putting %* in quotes you were making the entire commandline one single token. also, the /F variant of FOR isn't what you were looking for either. The documentation available from FOR /? should help clear things up.

like image 176
MarbleMunkey Avatar answered Oct 19 '22 06:10

MarbleMunkey


You could loop over the arguments using SHIFT, GOTO and an extra IF to check if there are no more parameters to parse:

:loop
IF "%~1"=="" GOTO cont
IF /I "%~1"=="/u" SET UPDATE=Y
IF /I "%~1"=="/p" SET PRIMARY=Y
IF /I "%~1"=="/s" SET SECONDARY=Y
SHIFT & GOTO loop

:cont
...

UPDATE (addressing the case when a parameter has an argument of its own)

The SHIFT in the IF statement that checks for /d does work. The issue is that the entire line is evaluated at once and both instances of %~1 get replaced with the same value, which is /d at that point.

So, basically the solution in this case would be to cause the interpreter to evaluate the SET DISTRO="%~1" part separately from the IF /I "%~1"=="/d". There can be various approaches to this. For instance, you could simply move SHIFT & SET DISTRO="%~1" to the next line and skip it if %~1 is not /d:

...
IF /I NOT "%~1"=="/d" GOTO skip_d
SHIFT & SET "DISTRO=%~1"
:skip_d
...

Another method could be to assign a special value (e.g. a ?) to DISTRO and shift when /d is encountered. Then, on the next line, check if DISTRO has that special value and set it to %~1:

...
IF /I "%~1"=="/d" SHIFT & SET DISTRO=?
IF "%DISTRO%"=="?" SET "DISTRO=%~1"
...
like image 23
Andriy M Avatar answered Oct 19 '22 07:10

Andriy M