Passing parametric input parameter to batch file - batch-file

This might be a simple question, but I didn't found any thread, may be I am searching wrong.
I am having a simple bat script and passing some arguments. Currently I am getting the argument based on there order. But I want to make simple for the user.
My current command line looks like: testBatch.bat setupip setupuser setuppass
My current batch script looks like:
set setupip=%1
set setupuser=%2
set setuppass=%3
echo I am doing some operation after this based on the input I got.
Now I want to modify the command such that the user should not be woried about the order of argument to pass. Basically I want to see my command like this: testBatch.bat --ip setupip --user setupuser --password setuppass
What modification I have to do in my batch script?

try this:
#echo off
for %%a in (%*) do (
call set "%%~1=%%~2"
shift
)
echo :%--user%
echo :%--pass%
if the passed it is called like:
namedArgs.bat --user user --pass pass
the output will be like:
:user
:pass
This will handle also quoted parameters with spaces in them.

Thing you are looking for is called 'Named Arguments'. I found link for same question here.
Answer Which I like from that link is as follow:
set c=defaultC
set s=defaultS
set u=defaultU
:initial
if "%1"=="" goto done
echo %1
set aux=%1
if "%aux:~0,1%"=="-" (
set nome=%aux:~1,250%
) else (
set "%nome%=%1"
set nome=
)
shift
goto initial
:done
echo %c%
echo %s%
echo %u%
Run the following command:
arguments.bat -c users -u products
Will generate the following output:
users
defaultS
products

There is a batch command called shift, which can basically do a shift left on your parameter variables.
So as the start of your script, you need a loop
inside that loop you decode %1 for the 'verb' part of your option with a if statement
inside that if block, you call shift. then old %2 becomes the new%1, old %3 becomes the new %2, etc
so inside that if, you can pick up a secondary argument for the verb, if needed. Then call shift again.
loop until your arguments are empty. Tadah!

Related

Writing a Batch Program from Local System Variables Using the Set Command

I'm required to write a program that displays the computer name, username, and path to user files. All of these should be taken from local system variables. It's been hinted that I'm supposed to use the set command, however, I'm not sure how to use the set command in this situation... I had assumed that I could just use echo %COMPUTERNAME% etc. How can I implement the set command?
I'm guessing that the hint about the Set command was so that you could use the output of it to help you identify the local system variables to use in your batch file, not that you need to use Set to output them.
When you enter Set at the Command prompt you'll get output showing you each of the defined system variables.
Additionally, if you enter Set ComputerName at the prompt, you should get output showing you all variables which begin with the string ComputerName.
So based on the output of the Set command you could Echo, your three variables from a batch file like this:
#Echo Off
Echo %ComputerName%
Echo %UserName%
Echo %UserProfile%
You could also include the variables with their values:
#Echo Off
Echo %%ComputerName%%=%ComputerName%
Echo %%UserName%%=%UserName%
Echo %%UserProfile%%=%UserProfile%
You could also consider running a simple For loop in your batch file to show the same content using the Set command directly:
#Echo Off
For %%A In (ComputerName,UserName,UserProfile) Do Set %%A
Pause
Or you could return just their values using Set and Echo from nested For loops:
#Echo Off
For %%A In (ComputerName,UserName,UserProfile) Do (
For /F "Tokens=1* Delims==" %%B In ('Set %%A') Do Echo %%C)
Pause
to take the question very literal ("display the computer name ... using set command"):
set computername
set username
set userprofile
output like:
COMPUTERNAME=Elon-PC
USERNAME=Muscrat
USERPROFILE=C:\Users\Muskrat
(Compo already has this method in his answer, but I guess using the for command is over the boundaries of the current state of your course)
(Note: for practical use, in most cases Compo's answer (using variables) is better, because in practice, you will probably do something with the values, not "just" show them, but this literally answers your question)

batch multiple variable to one / double quotes

Hi guys im trying to add multiple variables to one.
ET CA1="C:/Users/"
SET CA2=Bla
SET CA3="/New Folder/"
SET CA=%CA1%%CA2:~%%CA3%"
echo %CA%
This is the Output
"C:/Users/"Bla"/New Folder/"
When i do this i always get double quotes " in the middle no matter what i do.
I have tried to use :~1,-1%" to remove the last char but the output is just "l" in the middle.
The "end product" i want to archive is to ask the username by prompt and use the string for something else. This was the best ( and surely not best) i could think of. to add 3 different Variable to get the right path.
Is there maybe another way to just have something like this:
set /p Username="Insert Username" -> pete for example
set CA="C:/Users/%CA%/New Folder/"
echo %CA%
Output:
"C:/Users/pete/New Folder/"
As per your first example try this:
#echo off
SET "CA1=C:/Users/"
SET "CA2=Bla"
SET "CA3=/New Folder/"
SET "CA=%CA1%%CA2:~%%CA3%"
echo "%CA%"
pause
which simply echo's:
"C:/Users/Bla/New Folder/"
Note that you move the quotes to before the variable name, and not after the =
On the second part, where you require user input. there are 2 methods:
User input method
set /p "myuser=Insert Username: "
set "CA=C:/Users/%myuser%/New Folder/"
echo "%CA%"
pause
or Get the name from environment.
#echo off
set "CA=C:/Users/%username%/New Folder/"
echo "%CA%"
pause
Note, the second method gets the %username% variable of the user currently logged in from the environment and will set it automatically.
Finally, some hints. always use help from cmd.exe to find relevant commands
Use each command with the /?switch to get more information on it's abilities. i.e set /?
Also, NEVER modify existing environment variables. For instance in your example set /p Username="Insert Username.. %username% is already an existing environment variable, rather create something unique likemysername`
To test this, simple do from cmd.exe echo %username% and to understand where it got it from, simply run set to display Environment variables.

Checking parameters for information

I have a Script that reads other .bat Files and counts the Commentlines. I pass the .bat file that i want to test as a parameter.
For example, this is how i start my script.
C:\User\User\Desktop>CommentReader.bat test.bat
Right now test.bat needs to be in the same folder with the Skript.
I want the option that I can pass multiple .bat files that need testing and the option that I can pass the path too. for example:
C:\User\User\Desktop>CommentReader.bat D:\testfolder\test1.bat E:\test2.bat test3.bat
I also want to pass commands for example /l so the script also reads empty lines.
C:\User\User\Desktop>CommentReader.bat /l D:\testfolder\test1.bat E:\test2.bat test3.bat
I know how I can code that it should also read empty lines but
what is the best way to go through my parameters and check the information?
My Idea was something like this:
FOR /f tokens=1,2,3,4,5,6,7,8,9, delims= " %%a in (%*) DO (
)
But maybe there is a better way?
As Stephan stated in the comments section, SHIFT is what you're looking for. This script will loop through all parameters and echo them out. Just replace the ECHO command with your actual code.
#ECHO OFF
:LOOP
IF NOT "%1"=="" (
ECHO %1
SHIFT
GOTO LOOP
)
Your first parameter is always %1, the second one is %2 and so on. The SHIFT command will "forget" the original %1 and decrease all indices by 1, so %2 will become %1, %3 will become %2 and so on. As soon as you reach the last argument SHIFT will turn %1 into an empty string so that you beak out of the loop.

input a variable name and display - BATCH FILE

I wanted the user insert a variable and then be displayed with echo It would be something like %%var%%
A variable inside another variable
set var=value
set x=var
setlocal enableDelayedExpansion
echo !%x%!
...
endlocal
This should outperfrom the call approach.
I hope I got your question right. You need an additional parse-phase. this can be done with call:
set var=value
set x=var
call echo %%%x%%%
REM on commandline: call echo %%x%%
(yes, that's ugly, but it works)

Batch file include external file for variables

I have a batch file and I want to include an external file containing some variables (say configuration variables). Is it possible?
Note: I'm assuming Windows batch files as most people seem to be unaware that there are significant differences and just blindly call everything with grey text on black background DOS. Nevertheless, the first variant should work in DOS as well.
Executable configuration
The easiest way to do this is to just put the variables in a batch file themselves, each with its own set statement:
set var1=value1
set var2=value2
...
and in your main batch:
call config.cmd
Of course, that also enables variables to be created conditionally or depending on aspects of the system, so it's pretty versatile. However, arbitrary code can run there and if there is a syntax error, then your main batch will exit too. In the UNIX world this seems to be fairly common, especially for shells. And if you think about it, autoexec.bat is nothing else.
Key/value pairs
Another way would be some kind of var=value pairs in the configuration file:
var1=value1
var2=value2
...
You can then use the following snippet to load them:
for /f "delims=" %%x in (config.txt) do (set "%%x")
This utilizes a similar trick as before, namely just using set on each line. The quotes are there to escape things like <, >, &, |. However, they will themselves break when quotes are used in the input. Also you always need to be careful when further processing data in variables stored with such characters.
Generally, automatically escaping arbitrary input to cause no headaches or problems in batch files seems pretty impossible to me. At least I didn't find a way to do so yet. Of course, with the first solution you're pushing that responsibility to the one writing the config file.
If the external configuration file is also valid batch file, you can just use:
call externalconfig.bat
inside your script. Try creating following a.bat:
#echo off
call b.bat
echo %MYVAR%
and b.bat:
set MYVAR=test
Running a.bat should generate output:
test
Batch uses the less than and greater than brackets as input and output pipes.
>file.ext
Using only one output bracket like above will overwrite all the information in that file.
>>file.ext
Using the double right bracket will add the next line to the file.
(
echo
echo
)<file.ext
This will execute the parameters based on the lines of the file. In this case, we are using two lines that will be typed using "echo". The left bracket touching the right parenthesis bracket means that the information from that file will be piped into those lines.
I have compiled an example-only read/write file. Below is the file broken down into sections to explain what each part does.
#echo off
echo TEST R/W
set SRU=0
SRU can be anything in this example. We're actually setting it to prevent a crash if you press Enter too fast.
set /p SRU=Skip Save? (y):
if %SRU%==y goto read
set input=1
set input2=2
set /p input=INPUT:
set /p input2=INPUT2:
Now, we need to write the variables to a file.
(echo %input%)> settings.cdb
(echo %input2%)>> settings.cdb
pause
I use .cdb as a short form for "Command Database". You can use any extension.
The next section is to test the code from scratch. We don't want to use the set variables that were run at the beginning of the file, we actually want them to load FROM the settings.cdb we just wrote.
:read
(
set /p input=
set /p input2=
)<settings.cdb
So, we just piped the first two lines of information that you wrote at the beginning of the file (which you have the option to skip setting the lines to check to make sure it's working) to set the variables of input and input2.
echo %input%
echo %input2%
pause
if %input%==1 goto newecho
pause
exit
:newecho
echo If you can see this, good job!
pause
exit
This displays the information that was set while settings.cdb was piped into the parenthesis. As an extra good-job motivator, pressing enter and setting the default values which we set earlier as "1" will return a good job message.
Using the bracket pipes goes both ways, and is much easier than setting the "FOR" stuff. :)
So you just have to do this right?:
#echo off
echo text shizzle
echo.
echo pause^>nul (press enter)
pause>nul
REM writing to file
(
echo XD
echo LOL
)>settings.cdb
cls
REM setting the variables out of the file
(
set /p input=
set /p input2=
)<settings.cdb
cls
REM echo'ing the variables
echo variables:
echo %input%
echo %input2%
pause>nul
if %input%==XD goto newecho
DEL settings.cdb
exit
:newecho
cls
echo If you can see this, good job!
DEL settings.cdb
pause>nul
exit
:: savevars.bat
:: Use $ to prefix any important variable to save it for future runs.
#ECHO OFF
SETLOCAL
REM Load variables
IF EXIST config.txt FOR /F "delims=" %%A IN (config.txt) DO SET "%%A"
REM Change variables
IF NOT DEFINED $RunCount (
SET $RunCount=1
) ELSE SET /A $RunCount+=1
REM Display variables
SET $
REM Save variables
SET $>config.txt
ENDLOCAL
PAUSE
EXIT /B
Output:
$RunCount=1
$RunCount=2
$RunCount=3
The technique outlined above can also be used to share variables among multiple batch files.
Source: http://www.incodesystems.com/products/batchfi1.htm
Kinda old subject but I had same question a few days ago and I came up with another idea (maybe someone will still find it usefull)
For example you can make a config.bat with different subjects (family, size, color, animals) and apply them individually in any order anywhere you want in your batch scripts:
#echo off
rem Empty the variable to be ready for label config_all
set config_all_selected=
rem Go to the label with the parameter you selected
goto :config_%1
REM This next line is just to go to end of file
REM in case that the parameter %1 is not set
goto :end
REM next label is to jump here and get all variables to be set
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set sister=Anna
rem This next line is to skip going to end if config_all label was selected as parameter
if not "%config_all_selected%"=="1" goto :end
:config_test
set "test_parameter_all=2nd set: The 'all' parameter WAS used before this echo"
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:config_color
set first_color=blue
set second_color=green
if not "%config_all_selected%"=="1" goto :end
:config_animals
set dog=Max
set cat=Miau
if not "%config_all_selected%"=="1" goto :end
:end
After that, you can use it anywhere by calling fully with 'call config.bat all' or calling only parts of it (see example bellow)
The idea in here is that sometimes is more handy when you have the option not to call everything at once. Some variables maybe you don't want to be called yet so you can call them later.
Example test.bat
#echo off
rem This is added just to test the all parameter
set "test_parameter_all=1st set: The 'all' parameter was NOT used before this echo"
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
call config.bat animals
echo Yesterday %father% and %mother% surprised %sister% with a cat named %cat%
echo Her brother wanted the dog %dog%
rem This shows you if the 'all' parameter was or not used (just for testing)
echo %test_parameter_all%
call config.bat color
echo His lucky color is %first_color% even if %second_color% is also nice.
echo.
pause
Hope it helps the way others help me in here with their answers.
A short version of the above:
config.bat
#echo off
set config_all_selected=
goto :config_%1
goto :end
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set daughter=Anna
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:end
test.bat
#echo off
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
echo %father% and %mother% have a daughter named %daughter%
echo.
pause
Good day.
The best option according to me is to have key/value pairs file as it could be read from other scripting languages.
Other thing is I would prefer to have an option for comments in the values file - which can be easy achieved with eol option in for /f command.
Here's the example
values file:
;;;;;; file with example values ;;;;;;;;
;; Will be processed by a .bat file
;; ';' can be used for commenting a line
First_Value=value001
;;Do not let spaces arround the equal sign
;; As this makes the processing much easier
;; and reliable
Second_Value=%First_Value%_test
;;as call set will be used in reading script
;; refering another variables will be possible.
Third_Value=Something
;;; end
Reading script:
#echo off
:::::::::::::::::::::::::::::
set "VALUES_FILE=E:\scripts\example.values"
:::::::::::::::::::::::::::::
FOR /F "usebackq eol=; tokens=* delims=" %%# in (
"%VALUES_FILE%"
) do (
call set "%%#"
)
echo %First_Value% -- %Second_Value% -- %Third_Value%
While trying to use the method with excutable configuration
I noticed that it may work or may NOT work
depending on where in the script is located the call:
call config.cmd
I know it doesn't make any sens, but for me it's a fact.
When "call config.cmd" is located at the top of the
script, it works, but if further in the script it doesn't.
By doesn't work, I mean the variable are not set un the calling script.
Very very strange !!!!

Resources