string comparison in batch file - windows

How do we compare strings which got space and special chars in batch file?
I am trying:
if %DevEnvDir% == "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\"(
echo VS2010
)
But it gives an error "Files was unexpected at this time."
I tried:
if "%DevEnvDir%" == "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\"(
echo VS2010
)
But it gives an error "The syntax of the command is incorrect."
Any ideas?

Just put quotes around the Environment variable (as you have already done):
if "%DevEnvDir%" == "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\"
The strings you are comparing are fine, the problem is the way you put the opening bracket without a space. That is confusing it.
Works for me...
C:\if "%gtk_basepath%" == "C:\Program Files\GtkSharp\2.12\" (echo yes)
yes

While #ajv-jsy's answer works most of the time, I had the same problem as #MarioVilas. If one of the strings to be compared contains a double quote ("), the variable expansion throws an error.
Example:
#echo off
SetLocal
set Lhs="
set Rhs="
if "%Lhs%" == "%Rhs%" echo Equal
Error:
echo was unexpected at this time.
Solution:
Enable delayed expansion and use ! instead of %.
#echo off
SetLocal EnableDelayedExpansion
set Lhs="
set Rhs="
if !Lhs! == !Rhs! echo Equal
:: Surrounding with double quotes also works but appears (is?) unnecessary.
if "!Lhs!" == "!Rhs!" echo Equal
I have not been able to break it so far using this technique. It works with empty strings and all the symbols I threw at it.
Test:
#echo off
SetLocal EnableDelayedExpansion
:: Test empty string
set Lhs=
set Rhs=
echo Lhs: !Lhs! & echo Rhs: !Rhs!
if !Lhs! == !Rhs! (echo Equal) else (echo Not Equal)
echo.
:: Test symbols
set Lhs= \ / : * ? " ' < > | %% ^^ ` ~ # # $ [ ] & ( ) + - _ =
set Rhs= \ / : * ? " ' < > | %% ^^ ` ~ # # $ [ ] & ( ) + - _ =
echo Lhs: !Lhs! & echo Rhs: !Rhs!
if !Lhs! == !Rhs! (echo Equal) else (echo Not Equal)
echo.

A roundabout solution use a subroutine
CALL :Comparator %var1% %var2% <- or the string you want to compare
IF %retVal%==1 (
do stuff
) ELSE (
do other things
)
GOTO :eof
:Comparator
IF "%~1" == "%~2" (set retVal=1) ELSE (set retVal=0)
GOTO :eof
It won't work if there is double-quotes inside the strings though, but if you compare file paths, there shouldn't be.
%~[1-9] the tilde '~' removes double quotes around the variable, and then you put new ones around them if the strings has spaces inside. The tilde trick only works with passed variable though, hence the subroutine.

The solution is DO NOT USE SPACES!
IF "%DevEnvDir%"=="C:\" (

Related

Echoing a variable value containing closing parentheses within a parenthesized block

Let's suppose we have the following environment variable:
set "VS140COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\"
It's ok to print its value like that:
echo VS140COMNTOOLS=%VS140COMNTOOLS%
But if we will print it inside if body, IE:
if "" == "" (
echo VS140COMNTOOLS=%VS140COMNTOOLS%
)
We will get the following error:
\Microsoft was unexpected at this time.
Ok, we can workaround it by quoting what we are echo-ing:
if "" == "" (
echo "VS140COMNTOOLS=%VS140COMNTOOLS%"
)
And get:
"VS140COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\"
But what to do if we don't want to see double quotes around the message?
Does the following help you out?
#Set "VS140COMNTOOLS=%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\Common7\Tools"
#Echo VS140COMNTOOLS=%VS140COMNTOOLS%
#If "" == "" (
Echo VS140COMNTOOLS=%VS140COMNTOOLS:)=^)%
)
#If "" == "" (
SetLocal EnableDelayedExpansion
Echo VS140COMNTOOLS=!VS140COMNTOOLS!
EndLocal
)
#If "" == "" (
For %%G In ("%VS140COMNTOOLS%") Do #Echo VS140COMNTOOLS=%%~G
)
#Pause
#Rem Additional as per comment section
#If "" == "1" (
Echo VS140COMNTOOLS!=%VS140COMNTOOLS:)=^)%
) Else (
Echo VS140COMNTOOLS=%VS140COMNTOOLS:)=^)%
)
#If "" == "1" (
Echo VS140COMNTOOLS!=%VS140COMNTOOLS:)=^)%
) Else Echo VS140COMNTOOLS=%VS140COMNTOOLS:)=^)%
#Pause
You'll note that I removed the trailing backward slash from your initial set value string. It is uncommon that directory paths need to have a trailing backward slash, as those are technically just path separators, and you aren't separating one in that position. If you need to use one, then use it when needed outside of the variable itself, e.g. If Exist "%VS140COMNTOOLS%\" …

How can I check if a variable contains another variable within a windows batch file?

Assuming the following batch file
set variable1=this is variable1
set variable2=is
set variable3=test
if variable1 contains variable2 (
echo YES
) else (
echo NO
)
if variable1 contains variable3 (
echo YES
) else (
echo NO
)
I want the output to be a YES followed by a NO
I've resolved this with the following
setLocal EnableDelayedExpansion
set variable1=this is variable1
set variable2=is
set variable3=test
if not "x!variable1:%variable2%=!"=="x%variable1%" (
echo YES
) else (
echo NO
)
if not "x!variable1:%variable3%=!"=="x%variable1%" (
echo YES
) else (
echo NO
)
endlocal
I got the basic idea from the following answer but it wasn't searching by a variable so it wasn't completely what I was looking for.
Batch file: Find if substring is in string (not in a file)
another way:
echo/%variable1%|find "%variable2%" >nul
if %errorlevel% == 0 (echo yes) else (echo no)
the / prevents output of Echo is ON or Echo is OFF in case %variable1% is empty.
Gary Brunton's answer did not work for me.
If you try with set variable1="C:\Users\My Name\", you will end up with an error :
'Name\""' is not recognized as an internal or external command
Adapting this answer Find out whether an environment variable contains a substring, I ended up with :
echo.%variable1%|findstr /C:"%variable2%" >nul 2>&1
if not errorlevel 1 (
echo Found
) else (
echo Not found
)
The following is based on JBEs answer in this thread. It distinguishes empty/undefined variables.
if not defined VARIABLE1 (echo VARIABLE1 undefined) & goto proceed
if not defined VARIABLE2 (echo VARIABLE2 undefined) & goto proceed
echo %VARIABLE1% | find "%VARIABLE2%" > nul
if ERRORLEVEL 1 (echo Not found) & goto proceed
echo Found
:proceed
If the value of VARIABLE1 contains parentheses, e.g. the value C:\Program Files (x86), then the parentheses may be interpreted as a distinct command rather than echoed, causing an error. Substrings like (x86) can be escaped with carets for purposes of echoing properly, e.g.:
SET V1_DISPLAY=%VARIABLE1%
if /i "%V1_DISPLAY:(x86)=%" NEQ "%V1_DISPLAY%" set V1_DISPLAY=%V1_DISPLAY:(x86)=^^(x86^^)%
echo %V1_DISPLAY% | find "%VARIABLE2%" > nul
The second statement, above, can be read as follows:
If replacing substring (x86) with nothing makes a difference, then (x86) is present, so replace any occurrence of (x86) with ^^(x86^^), where each pair of carets represent an escaped single caret.

Echo of String with Double Quotes to Output file using Windows Batch

I'm attempting to rewrite a configuration file using a Windows Batch file.
I'm looping through the lines of the file and looking for the line that I want to replace with a specified new line.
I have a 'function' that writes the line to the file
:AddText %1 %2
set Text=%~1%
set NewLine=%~2%
echo "%Text%" | findstr /C:"%markerstr%" 1>nul
if errorlevel 1 (
if not "%Text%" == "" (
setlocal EnableDelayedExpansion
(
echo !Text!
) >> outfile.txt
) else (
echo. >> outfile.txt
)
) else (
set NewLine=%NewLine"=%
setlocal EnableDelayedExpansion
(
echo !NewLine!
) >> outfile.txt
)
exit /b
The problem is when %Text% is a string with embedded double quotes.
Then it fails. Possibly there are other characters that would cause it to fail too.
How can I get this to be able to work with all text found in the configuration file?
Try replacing all " in Text with ^".
^ is escape character so the the " will be treated as regular character
you can try the following:
:AddText %1 %2
set _Text=%~1%
set Text=%_Text:"=^^^"%
... rest of your code
REM for example if %1 is "blah"blah"blah"
REM _Text will be blah"blah"blah
REM Text will be blah^"blah^"blah
Other characters that could cause you errors (you can solve it with the above solution) are:
\ & | > < ^
In a windows batch shell (command) double quote are escape with ^ on standard command line BUT with a double double quote inside a double quoted string
echo Hello ^"Boy^"
echo "Hello ""Boy"""
(remark: second line will produce the external surrounding double quote in the output also)

IF... OR IF... in a windows batch file

Is there a way to write an IF OR IF conditional statement in a windows batch-file?
For example:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
The zmbq solution is good, but cannot be used in all situations, such as inside a block of code like a FOR DO(...) loop.
An alternative is to use an indicator variable. Initialize it to be undefined, and then define it only if any one of the OR conditions is true. Then use IF DEFINED as a final test - no need to use delayed expansion.
FOR ..... DO (
set "TRUE="
IF cond1 set TRUE=1
IF cond2 set TRUE=1
IF defined TRUE (
...
) else (
...
)
)
You could add the ELSE IF logic that arasmussen uses on the grounds that it might perform a wee bit faster if the 1st condition is true, but I never bother.
Addendum - This is a duplicate question with nearly identical answers to Using an OR in an IF statement WinXP Batch Script
Final addendum - I almost forgot my favorite technique to test if a variable is any one of a list of case insensitive values. Initialize a test variable containing a delimitted list of acceptable values, and then use search and replace to test if your variable is within the list. This is very fast and uses minimal code for an arbitrarily long list. It does require delayed expansion (or else the CALL %%VAR%% trick). Also the test is CASE INSENSITIVE.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" (echo true) else (echo false)
The above can fail if VAR contains =, so the test is not fool-proof.
If doing the test within a block where delayed expansion is needed to access current value of VAR then
for ... do (
set "TEST=;val1;val2;val3;val4;val5;"
for /f %%A in (";!VAR!;") do if "!TEST:%%A=!" neq "!TEST!" (echo true) else (echo false)
)
FOR options like "delims=" might be needed depending on expected values within VAR
The above strategy can be made reliable even with = in VAR by adding a bit more code.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" if "!TEST:;%VAR%;=;%VAR%;"=="!TEST!" echo true
But now we have lost the ability of providing an ELSE clause unless we add an indicator variable. The code has begun to look a bit "ugly", but I think it is the best performing reliable method for testing if VAR is any one of an arbitrary number of case-insensitive options.
Finally there is a simpler version that I think is slightly slower because it must perform one IF for each value. Aacini provided this solution in a comment to the accepted answer in the before mentioned link
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A echo true
The list of values cannot include the * or ? characters, and the values and %VAR% should not contain quotes. Quotes lead to problems if the %VAR% also contains spaces or special characters like ^, & etc. One other limitation with this solution is it does not provide the option for an ELSE clause unless you add an indicator variable. Advantages are it can be case sensitive or insensitive depending on presence or absence of IF /I option.
I don't think so. Just use two IFs and GOTO the same label:
IF cond1 GOTO foundit
IF cond2 GOTO foundit
ECHO Didn't find it
GOTO end
:foundit
ECHO Found it!
:end
A simple "FOR" can be used in a single line to use an "or" condition:
FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}
Applied to your case:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE
Suppress executing twice
A comment pointed out that {execute_command} may be encountered twice. To avoid this, you can use a goto after the first encounter.
FOR %%a in (1 2) DO IF %var%==%%a (
ECHO TRUE
goto :continue
)
:continue
If you think there's a possibility that {execute_command} might be executed twice and you don't want that, you can just add && goto :eof:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE && goto :eof
Much simpler, and still on a single line.
Thanks for this post, it helped me a lot.
Dunno if it can help but I had the issue and thanks to you I found what I think is another way to solve it based on this boolean equivalence:
"A or B" is the same as "not(not A and not B)"
Thus:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Becomes:
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
Even if this question is a little older:
If you want to use if cond1 or cond 2 - you should not use complicated loops or stuff like that.
Simple provide both ifs after each other combined with goto - that's an implicit or.
//thats an implicit IF cond1 OR cond2 OR cond3
if cond1 GOTO doit
if cond2 GOTO doit
if cond3 GOTO doit
//thats our else.
GOTO end
:doit
echo "doing it"
:end
Without goto but an "inplace" action, you might execute the action 3 times, if ALL conditions are matching.
There is no IF <arg> OR or ELIF or ELSE IF in Batch, however...
Try nesting the other IF's inside the ELSE of the previous IF.
IF <arg> (
....
) ELSE (
IF <arg> (
......
) ELSE (
IF <arg> (
....
) ELSE (
)
)
The goal can be achieved by using IFs indirectly.
Below is an example of a complex expression that can be written quite concisely and logically in a CMD batch, without incoherent labels and GOTOs.
Code blocks between () brackets are handled by CMD as a (pathetic) kind of subshell. Whatever exit code comes out of a block will be used to determine the true/false value the block plays in a larger boolean expression. Arbitrarily large boolean expressions can be built with these code blocks.
Simple example
Each block is resolved to true (i.e. ERRORLEVEL = 0 after the last statement in the block has executed) / false, until the value of the whole expression has been determined or control jumps out (e.g. via GOTO):
((DIR c:\xsgdde /w) || (DIR c:\ /w)) && (ECHO -=BINGO=-)
Complex example
This solves the problem raised initially. Multiple statements are possible in each block but in the || || || expression it's preferable to be concise so that it's as readable as possible. ^ is an escape char in CMD batches and when placed at the end of a line it will escape the EOL and instruct CMD to continue reading the current batch of statements on the next line.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
(CALL :ProcedureType1 a b) ^
|| (CALL :ProcedureType2 sgd) ^
|| (CALL :ProcedureType1 c c)
) ^
&& (
ECHO -=BINGO=-
GOTO :EOF
)
ECHO -=no bingo for you=-
GOTO :EOF
:ProcedureType1
IF "%~1" == "%~2" (EXIT /B 0) ELSE (EXIT /B 1)
GOTO :EOF (this line is decorative as it's never reached)
:ProcedureType2
ECHO :ax:xa:xx:aa:|FINDSTR /I /L /C:":%~1:">nul
GOTO :EOF
It's possible to use a function, which evaluates the OR logic and returns a single value.
#echo off
set var1=3
set var2=5
call :logic_or orResult "'%var1%'=='4'" "'%var2%'=='5'"
if %orResult%==1 (
echo At least one expression is true
) ELSE echo All expressions are false
exit /b
:logic_or <resultVar> expression1 [[expr2] ... expr-n]
SETLOCAL
set "logic_or.result=0"
set "logic_or.resultVar=%~1"
:logic_or_loop
if "%~2"=="" goto :logic_or_end
if %~2 set "logic_or.result=1"
SHIFT
goto :logic_or_loop
:logic_or_end
(
ENDLOCAL
set "%logic_or.resultVar%=%logic_or.result%"
exit /b
)
If %x%==1 (
If %y%==1 (
:: both are equal to 1.
)
)
That's for checking if multiple variables equal value. Here's for either variable.
If %x%==1 (
:: true
)
If %x%==0 (
If %y%==1 (
:: true
)
)
If %x%==0 (
If %y%==0 (
:: False
)
)
I just thought of that off the top if my head. I could compact it more.
I realize this question is old, but I wanted to post an alternate solution in case anyone else (like myself) found this thread while having the same question. I was able to work around the lack of an OR operator by echoing the variable and using findstr to validate.
for /f %%v in ('echo %var% ^| findstr /x /c:"1" /c:"2"') do (
if %errorlevel% equ 0 echo true
)
While dbenham's answer is pretty good, relying on IF DEFINED can get you in loads of trouble if the variable you're checking isn't an environment variable. Script variables don't get this special treatment.
While this might seem like some ludicrous undocumented BS, doing a simple shell query of IF with IF /? reveals that,
The DEFINED conditional works just like EXIST except it takes an
environment variable name and returns true if the environment variable
is defined.
In regards to answering this question, is there a reason to not just use a simple flag after a series of evaluations? That seems the most flexible OR check to me, both in regards to underlying logic and readability. For example:
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true)
IF %some_string%=="desired result" (Set Evaluated_True=true)
IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
Obviously, they can be any sort of conditional evaluation, but I'm just sharing a few examples.
If you wanted to have it all on one line, written-wise, you could just chain them together with && like:
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true) && IF %some_string%=="desired result" (Set Evaluated_True=true) && IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
Never got exist to work.
I use
if not exist g:xyz/what goto h:
Else xcopy c:current/files g:bu/current
There are modifiers /a etc. Not sure which ones. Laptop in shop. And computer in office. I am not there.
Never got batch files to work above Windows XP
A much faster alternative I usually use is as follows, as I can "or" an arbitrary number of conditions that can fit in variable space
#(
Echo off
Set "_Match= 1 2 3 "
)
Set /a "var=3"
Echo:%_Match%|Find " %var% ">nul || (
REM Code for a false condition goes here
) && (
REM code for a true condition goes here.
)
it's quite simple, just use below
IF %var% == 1 (
ECHO TRUE)
IF %var% == 2 (
ECHO TRUE)
Another option is to display the current environment variables and exploit the default behaviour of FINDSTR:
FINDSTR "hello there" x.y searches for "hello" or "there" in file x.y.
So
SET | FINDSTR /I /X "var=1 var=2" >NUL
IF %ERRORLEVEL% EQU 0 (
ECHO TRUE
) ELSE (
ECHO FALSE
)
Where
/I Specifies that the search is not to be case-sensitive.
/X Prints lines that match exactly.
If regular expressions are preferred, use FINDSTR /R /I "^var=1$ ^var=2$" >NUL instead.
Edit: FINDSTR /R should be used if the variable string includes a space, e.g., FINDSTR /R /I "^var=1 a$ ^var=2 b$" >NUL.
Edit: If the variable string includes spaces, a literal search string should be used. E.g., FINDSTR /I /X /C:"var=1 a" /C:"var=2 b" >NUL.
There is no OR operator but you can write (the pseudocode)
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
like
IF "%var%" == "1" SET "match=y"
IF "%var%" == "2" SET "match=y"
IF DEFINED match ECHO TRUE
Note that the double quotes prevents a syntax error from being triggered if var is undefined.
I took bogdan's solution to the next level by building an extern function that is a callable and clean abstraction of IF, so it can be used in inline blocks. Don't look further, if you build a batch library anyways.
lib.cmd
#ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SHIFT & GOTO:%1
: Common batch extension library.
:::
: Performs conditional processing in batch programs. Is callable for inline use.
: Arguments:
: %1 - /I for case-insensitive comparison on strings, can be skipped for case-sensitive comparison.
: %2 - NOT to negate the result, can be skipped.
: %3 - EXIST for file checks or first string to compare with, also supports "string1"=="string2" (full condition).
: %4 - If EXIST is specified, path to the directory or file.
: Otherwise if %3 is not a full condition, this argument has to be one of:
: - == Compares both strings to be equal using lstrcmpW or lstrcmpiW (case-insensitive).
: - EQU Converts both strings to numbers and checks if they are equal.
: - NEQ Converts both strings to numbers and checks if they are not equal.
: - LSS Converts both strings to numbers and checks if the first is lesser than the second.
: - LEQ Converts both strings to numbers and checks if the first is lesser or equal than the second.
: - GTR Converts both strings to numbers and checks if the first is greater than the second.
: - GEQ Converts both strings to numbers and checks if the first is greater or equal than the second.
: If a string cannot be parsed to a number, its numeric representation will be used.
: This argument can be skipped, so == will be used.
: %5 - If %3 is not a full condition, this argument has to be the second string to compare.
: Outputs:
: Nothing
: Returns:
: 0, if the condition is met, 1 otherwise
:::
:test-if
IF "%~1"=="/I" SET "I=/I " & SHIFT
IF "%~1"=="/i" SET "I=/I " & SHIFT
IF "%~1"=="NOT" SET "NOT=NOT " & SHIFT
IF "%~1"=="not" SET "NOT=NOT " & SHIFT
IF "%~1"=="EXIST" SET "EXIST=EXIST " & SHIFT
IF "%~1"=="exist" SET "EXIST=EXIST " & SHIFT
SET "string1=%~1%"
IF "%~3"=="" (
SET "comp=^=^="
SET "string2=%~2"
) ELSE (
SET "comp=%~2"
SET "string2=%~3"
)
IF %I%%NOT%%EXIST% "%string1%" %comp% "%string2%" (
ENDLOCAL & EXIT /B 0
)
ENDLOCAL & EXIT /B 1
Usage
( ( CALL lib test-if "%1" == "foo" ) || ( CALL lib test-if "%1" == "bar" ) ) && (
ECHO "Argument is foo or bar"
)
lib is the path to the lib.cmd, the suffix .cmd is not mandatory for cmd-files
Any IF syntax is compatible with this abstraction, so you can also do things like test-if EXIST "path" or test-if not 300 LSS 200
The == in test-if "%1" == "foo" will be stripped away by batch and I address this fact in my case, but this causes test-if "%1" "foo" to be valid as well, it's not the standard though.
Realizing this is a bit of an old question, the responses helped me come up with a solution to testing command line arguments to a batch file; so I wanted to post my solution as well in case anyone else was looking for a similar solution.
First thing that I should point out is that I was having trouble getting IF ... ELSE statements to work inside of a FOR ... DO clause. Turns out (thanks to dbenham for inadvertently pointing this out in his examples) the ELSE statement cannot be on a separate line from the closing parens.
So instead of this:
FOR ... DO (
IF ... (
)
ELSE (
)
)
Which is my preference for readability and aesthetic reasons, you have to do this:
FOR ... DO (
IF ... (
) ELSE (
)
)
Now the ELSE statement doesn't return as an unrecognized command.
Finally, here's what I was attempting to do - I wanted to be able to pass several arguments to a batch file in any order, ignoring case, and reporting/failing on undefined arguments passed in. So here's my solution...
#ECHO OFF
SET ARG1=FALSE
SET ARG2=FALSE
SET ARG3=FALSE
SET ARG4=FALSE
SET ARGS=(arg1 Arg1 ARG1 arg2 Arg2 ARG2 arg3 Arg3 ARG3)
SET ARG=
FOR %%A IN (%*) DO (
SET TRUE=
FOR %%B in %ARGS% DO (
IF [%%A] == [%%B] SET TRUE=1
)
IF DEFINED TRUE (
SET %%A=TRUE
) ELSE (
SET ARG=%%A
GOTO UNDEFINED
)
)
ECHO %ARG1%
ECHO %ARG2%
ECHO %ARG3%
ECHO %ARG4%
GOTO END
:UNDEFINED
ECHO "%ARG%" is not an acceptable argument.
GOTO END
:END
Note, this will only report on the first failed argument. So if the user passes in more than one unacceptable argument, they will only be told about the first until it's corrected, then the second, etc.

Set variable in "if" block

The following program always echoes "machine-abc" in the end:
#echo Off
set dropLoc=machine-abc
IF %computername% == "xyz" (
%dropLoc% = machine-xyz
)
echo %dropLoc%
Is this a scope issue? Does the dropLoc variable in the if statement have a different scope? I have tried the following to address the issue:
#echo Off
set dropLoc=machine-abc
IF %computername% == "xyz" (
!dropLoc! = machine-xyz
)
echo %dropLoc%
and
#echo Off
set dropLoc=machine-abc
IF %computername% == "xyz" (
set dropLoc = machine-xyz
)
echo %dropLoc%
How do I make this work?
You got the SET syntax right the first time, how come you decided to write something else the second time round? Also, you have to add the quotation marks on both sides of the comparison. Unlike in other script interpreters, quotation marks aren't special for the batch interpreter.
#echo off
rem Change this for testing, remove for production
set computername=xyz
set dropLoc=machine-abc
if "%computername%" == "xyz" (
set dropLoc=machine-xyz
)
echo %dropLoc%

Resources