Passing argument in batch file - batch-file

Have seen passing argument to a batch file something like
filename.bat argument1 argument2 ..
But i want to pass something like
filename.bat username=argument1 password=argument2
As i dont want to depend on any order , user can pass password first and then username.

Look here : processing switches
Although this is oriented toward using the format /username argument1 it's relatively easy to adapt to username=argument1 but there is a problem with = when passed within "a" parameter - it's seen as a separator, so the receiving routine would see two parameters, but they'd be paired (username and argument1.)
Really depends on quite how you want to process the data. You can, if you so desire, pass the parameter "quoted" to get over the = is a separator problem, then use
for /f "tokens=1,*delims==" %%a in ("%~1") do set "%%a=%%b"
but remembering to use the quoting may be a stumbling block.
Note: using the procedure I've pointed to is not restricted by parameter-count.

I dont think you are able to pass parameters in a random order, as they are not identified by a parameter name, but by %0 - %9
see http://www.robvanderwoude.com/parameters.php
As mentioned here, you can use up tp 9 parameters when calling a batch file..

You could achieve this by using a variable substring since username= and password= are both 9 character long.
For example
set temp=%0
set temp=%temp:~0,9%
if %temp%=="username=" (
set tmpUser=%0
set username=%tmpUser:~9%
set tmpPass=%1
set password=%tmpPass:~9%
)
if %temp%=="password=" (
set tmpPass=%0
set password=%tmpPass:~9%
set tmpUser=%1
set username=%tmpUser:~9%
)

Related

IF command not working when using 'NOT or '==' to use CALL and use SET for setting a variable

I'm creating a simple program that will echo variables from SET /p strings into a nice, neat list. However, I am having trouble creating 2 working IF statements, one using NOT, and one using == to detect if one of my variables, %pwad%, is empty, or contains values. I want to use what the IF statement returns to set variable %finalpwad% to either "No pwad detected" or %pwad%.
How should I properly write this statement? Where might I need corrections, fixing the IF statements or maybe even the part where it sets %pwad% to %finalpwad%?
I have already tried fixing my call part and what they call from, but to no avail. I'm almost sure this is an IF statement issue, as I'm not too good with them, and always struggle reading the notes about the command from IF /?.
Here's a snippet of my code and the source of the problem I am having:
set /p pwad=Set a pwad (or none):
if %pwad% NOT [] call :yespwad & pause
if %pwad% == [] :nopwad & pause
:nopwad
set finalpwad=No pwad detected
goto :printout
:yespwad
set finalpwad=%pwad%
goto :printout
I expect the output to continue onto :printout, where it echoes all the variables the user enters, but it instead exits the program, and makes it so I can't find out whether it properly read my IF NOT or IF == statements. I rudimentarily added pauses to snuff out the problem and see where the source was, and I concluded it must the IF statements.
The help file clearly shows the proper syntax for comparing strings.
IF [NOT] string1==string2 command
It is recommended that you use quotes as well when comparing strings.
IF "string1"=="string2" command
IF comparisons are literal. Each side of the comparison has to match. Using brackets does not check for an empty string.
There also is an option to check if a variable is defined.
IF DEFINED VAR command
Looking at your logic you could essentially do this:
#echo off
set /p "pwad=Set a pwad (or none): "
IF DEFINED pwad (
set "finalpwad=%pwad%"
) ELSE (
set "finalpwad=No pwad detected"
)

Is it possible to 'split' the value of a set /p command in cmd?

Is it possible in CMD to partialy extract the value of a string from the set /p var=command and assign each part to some other different variables? I mean, let's say that we used the set /p var= command to read some input from the user, and the user typed in I am Joe . So, now the variable %var%="I am Joe" . Is it possible to assign the "I am" content of %var% to another variable and the "Joe" content to another one as well?
It kind of all depends on what you can expect from the given input. You could use substrings to subtract a fixed part of the input string, like this:
:: part1 = I am
set "part1=%var:~0,4%"
:: part2 = Joe
set "part2=%var:~5,7%"
But if the length of the input string is less than 5, the variable part2 will be undefined. As if you didn't give the variable any value.
:: Like this
set part2=
Another way to get parts of the input string is by tokenizing it. Like this:
for /f "tokens=1-3" %%a in ("%var%") do (
set "part1=%%a %%b"
set "part2=%%c"
)
But there are a couple of problems with this approach that you should be aware of. First of all, since the input is provided by the user it could contain reserved shell characters in combination with doubles quotes and such that could actually break the code. Second, the number of tokens to use and how to deal with them has to be predefined.

Removing a variable number of characters from front of a string in batch

I am trying to remove a changing number of characters from a string right now I have it as
set /A VAR=%VAR:~%Num%%
is there any way you can think to make this work.
I am currently trying to it with a goto loop so I can still reference the variable
If you want to look at my code in context you can look at it on github at thumbdown.camojackson.com
Well without seeing all your code I can give you some options.
For starters you do not use the /A option to do string manipulation.
1) Use delayed expansion.
set VAR=!VAR:~%Num%!
2) Use the CALL command to get an extra phase of expansion
CALL set VAR=%%VAR:~%Num%%%

How to check if a batch passed parameter exists?

How could I modify the following example code to check if the input parameter was given when starting the batch file?
Because the check IF NOT %MYDIR%==test fails and terminates the batch process if no paramter was provided.
SET MYDIR=%1
IF {no parameter given} OR NOT %MYDIR%==test (
ECHO dir is not "test"
)
It is surprisingly difficult to handle all possibilities when dealing with passed parameters. But the following strategy works under most "ordinary" situations.
if "%~1" equ "" echo arg 1 was not passed
It is important that the ~ modifier is used because you have no way of knowing if the passed argument is already enclosed in quotes. If an argument like "this&that" is passed and you don't first remove the quotes before adding your own, then you get if ""this&that"" equ "". The & is no longer quoted and your command no longer parses properly.
Strings cannot be completely empty, a common way to work around this constraint is to enclose strings in quotes like this
... OR NOT "%MYDIR%"=="test"
or you can add something meaningless without enclosing the string (ugly!)
... OR NOT XXX%MYDIR%==XXXtest

How to get a the directory path from a variable in a cmd batch file

Within my batch file I have a variable that contains a file path:
SET VAR1=C:\Folder1\Folder2\File.txt
I would like to extract on the directory structure and retreive:
C:\Folder1\Folder2\
I have read threads like this where I need to use %~dp0 where 0 I believe is passed as a parameter. I have tried %~dpVAR1 but that doesn't work. How can I get the output I'm looking for, but with a variable containing the file path?
Also, to make matters difficult, I have to perform all of this within an IF condition which means that once the variable is declared, I will need to refer to it with ! instead of % (I have declared setlocal enableextensions enabledelayedexpansion at the beginning of my script to allow for this).
Any help is much appreciated!
Thanks!
Andrew
You are attempting to use parameter expansion syntax on an environment variable - that cannot work. But it is relatively easy to do what you want.
Using a CALL (relatively slow):
(...
call :getPath "!var!" var
...
)
exit /b
:getPath
set "%2=%~dp1"
exit /b
Using FOR, assuming the variable does not contain any wildcards (fast)
(...
for %%F in ("!var!") do set "var=%%~dpF"
...
)
Using FOR, if the variable may contain wildcards (also fast)
(...
for /f "delims=" %%F in ("!var!") do set "var=%%~dpF"
...
)
Note 1: If the variable does not contain the full path, then all the solutions will attempt to resolve the name into an absolute path and will return the full absolute path. For example, if var contains foobar\test.txt, then the solutions will include the full path to the current directory, even if the file is not found. Something like c:\pathToCurrentDirectory\foobar\.
Note 2: All solutions above will remove all quotes from the path.
Note 3: A path could include the ! character, which will cause problems when expanding %~dp1 or %%~dpF because you have delayed expansion enabled. The delayed expansion will corrupt both ^ and ! if the value contains !. There is a solution that involves protecting both ! and ^. Here is a demonstration applied to the last solution above. The protection requires normal expansion, and since you are within a code block, it requires at least one CALL. It could be done without a subroutine, but it is easier with a subroutine. The subroutine assumes the variable is named var.
(...
call :getPath
...
)
exit /b
:getPath
set "var=!var:"=!"
set "var=!var:^=^^^^!"
set "var=%var:!=^^^!%" !
for /f "delims=" %%F in ("!var!") do set "var=%%~dpF" !
exit /b
I do believe (once again) many questions are on the same topic (string constraints, or splitting strings).
Instead of giving you the whole code, I'm going to give you a template and explain why %~dpVAR! didn't work.
Firstly, why %~dpVAR! did't work.
Before I get into modifiers, let's discuss parameters. You may know that batch files can parse parameters to each other. These parameters can be called by using a single percent sign (%) in front of the numbers 0-9. As far as I'm aware (someone might have made a way for more to be parsed), only 9 parameters can be parsed. You may think that is wrong (there's 10 parameters right?). Parameters 1-9 are parsed to the batch file (or function within one), %0 is the file path of the batch file (or function name). If you look, %~dp0 shares some (not really) resemblance to %0. This will be discussed below.
Secondly, the term %~dp0 has modifiers in it. Modifiers are things that modify variables (only in the case of parameters and those declared in for loops, you know the ones with double percent signs like %%i) and parameters. The modifier d expands the parameter to a drive letter only while p expands the parameter to a path only. You may think that these would contradict themselves, but parameters can be combined to create extremely wacky formats.
So, as you can see, you attempt at replacing 0 with your variable name failed because it's not specified for those sort of things.
Now, on to the template.
You can constrain variables (and put them into other variables) like this:
set variable=!variable:~offset,amount!
Don't worry if that seems confusing, I'm about to explain the components.
Firstly, notice that there is no /a switch. This is because this is not a mathematical function (don't really know why I added this). So, before I explain it, here's an example of what it would do to a variable name numbers that has the value of 0123456789.
set numbers=!numbers:~5,1!
By using that line of code, numbers would now equal 5. This is because it is recreating the variable with a smaller version of the original value (gee this is hard to explain). As you can see, there is a 5 where offset was on the template above. This is because it is skipping the first 5 characters and setting the variable as the next amount, or 1 character (I really hope you're getting this).
So basically, it sets a variable as a shorter value of a different (or the same) variable determined by the offset and the amount of characters to contain in it.
I really hope this helps because I probably wouldn't understand a word of this.
Can someone redirect this poor guy to a link explaining this better (I tried, ok!)?
Complete example of extracting paths from variable:
#echo off
set /p Fullpath="Specify full path: "
call :getPath %Fullpath% filename folder
echo %filename%
echo %folder%
pause
exit /b
:getPath
set "%2=%~nx1"
set "%3=%~dp1"
exit /b
Would this work:
SET VAR1=C:\Folder1\Folder2\File.txt
echo %var1%
Where Echo is the name of your exe.
%CD% may work as well: Echo %CD%

Resources