Reputation: 35
I try to batch a simple network script for 3 hours now and I'm stuck with the checking of the parameters.
I actually use
IF not "%~1"=="" ( IF not "%~2"=="" (
Set NHS_Network1 = %1
Set NHS_Router1 = %2
))
and still get a syntax error on execution.
This is what I already tried:
IF DEFINED
: does not work for parameterIF [%1]NEQ[] ( IF [%2]NEQ[] ( ... ))
results in error ( was unexpectedSo ... I'm confused right now. I have never done "complex" thing in batch, but I'm familiar with bash, C, C++, Java, ...
Full code which may have some errors because I'm stuck at the beginning.
REM #Configuration#
Set NHS_Network1 = 192.168.0.0/24
Set NHS_Router1 = 192.168.0.254
Set NHS_Network2 = 192.168.1.0/24
Set NHS_Router2 = 192.168.1.1
Set NHS_Gateway1 = 192.168.1.1
Set NHS_Gateway2 = 192.168.0.254
Echo Network Home Script V0.1
IF not "%~1"=="" ( IF not "%~2"=="" (
Echo Overwriting Configuration
REM #Reset#
Set NHS_Network1 = []
Set NHS_Router1 = []
Set NHS_Network2 = []
Set NHS_Router2 = []
Set NHS_Gateway1 = []
Set NHS_Gateway2 = []
REM #Variable setup#
Set NHS_Network1 = %1
Set NHS_Router1 = %2
))
IF not "%~3"=="" ( IF not "%~4"=="" (
Set NHS_Network2 = %3
Set NHS_Router2 = %4
))
IF not "%~5"==""(
Set NHS_Gateway1 = %5
)
IF not "%~6"=="" (
Set NHS_Gateway2 = %6
)
IF DEFINED %NHS_Network1% ( IF DEFINED %NHS_Router1% (
route delete %NHS_Network1%
route add %NHS_Network1% %NHS_Router1%
IF %ERRORLEVEL% NEQ 0 (Echo ERROR : Impossible to add the route, please check route print) else (Echo Route Add)
))
IF DEFINED %NHS_Network2% ( IF DEFINED %NHS_Router2% (
route delete %NHS_Network2%
route add %NHS_Network2% %NHS_Router2%
IF %ERRORLEVEL% NEQ 0 (Echo ERROR : Impossible to add the route, please check route print) else (Echo Route Add)
))
IF DEFINED %NHS_Gateway1% (
route delete 0.0.0.0/0
route add 0.0.0.0/0 %NHS_Gateway1% metric 10
IF %ERRORLEVEL% NEQ 0 (Echo ERROR : Impossible to add the route, please check route print) else (Echo Route Add)
)
IF DEFINED %NHS_Gateway2% (
route add 0.0.0.0/0 %NHS_Gateway2% metric 20
IF %ERRORLEVEL% NEQ 0 (Echo ERROR : Impossible to add the route, please check route print) else (Echo Route Add)
)
Upvotes: 0
Views: 101
Reputation: 79982
@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
SET args=%*
FOR %%a IN (NHS_Network1:192.168.0.0/24
NHS_Router1:192.168.0.254
NHS_Network2:192.168.1.0/24
NHS_Router2:192.168.1.1
NHS_Gateway1:192.168.1.1
NHS_Gateway2:192.168.0.254
) DO FOR /f "tokens=1,2delims=:" %%v IN ("%%a") DO (
FOR /f "tokens=1*" %%t IN ('echo !args!') DO (
IF "%%~t"=="" (SET "%%v=%%w") ELSE (SET "%%v=%%~t")
IF DEFINED args (SET "args=%%u") ELSE (SET "%%v=%%w")
)
)
SET nhs
GOTO :EOF
Additional data may be added if desired - the format should be obvious.
Set args
to the argument list provided to the batch.
With each varname:varvalue, assign %%v
to the variablename and %%w
the default value.
set the variable to either the first remaining argument or the default
if there are remaining arguments, remove one. Otherwise, use the default.
Not quite exactly equivalent to the original, but might be useful.
Upvotes: 0
Reputation: 49086
Please read the answers on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for an explanation why it is in general no good idea in batch files to put 1 or more spaces around the equal sign on assigning a string to an environment variable.
And read this answer explaining correct syntax for IF conditions in batch files. Spaces must be used with care in batch files. On some positions a space is required, on other positions a space is often a mistake.
And care must be taken on referencing values of an environment variables within a block defined with (
... )
as command processor replaces all references to environment variables using %variable%
syntax by their values in entire block before processing the lines in block. For an environment variable defined or set within a block and also evaluated within a block it is necessary to enable delayed expansion and reference those variables with !variable!
to make used of delayed expansion. Even better is to avoid the need of delayed environment variable expansion.
goto is a keyword rarely used in C/C++. But in batch files it is a very important command and its usage makes most batch files much easier than using nested IF constructs used in C/C++ to avoid usage of goto.
There is a general rule on evaluating the parameters of a batch file:
If first parameter is not defined, there are definitely no more parameters.
Well, it is possible to use for example "" "second parameter" ThirdParameter
on calling a batch file to run it with 3 parameters whereby first one is an empty string. But for your script an empty string can be interpreted like parameter not specified at all.
Here is your batch file recoded with usage of goto and avoiding the need of delayed expansion.
@echo off
echo Network Home Script V0.1
setlocal
rem Default configuration
set "NHS_Network1=192.168.0.0/24"
set "NHS_Router1=192.168.0.254"
set "NHS_Network2=192.168.1.0/24"
set "NHS_Router2=192.168.1.1"
set "NHS_Gateway1=192.168.1.1"
set "NHS_Gateway2=192.168.0.254"
rem Run script with the defaults if executed without any
rem parameter or with just 1 parameter for first network.
if "%~1"=="" goto SetRoutes
if "%~2"=="" goto SetRoutes
rem IPv4 address with netmask and router address defined for network 1.
set "NHS_Network1=%~1"
set "NHS_Router1=%~2"
rem Delete all other by default defined environment variables.
set "NHS_Network2="
set "NHS_Router2="
set "NHS_Gateway1="
set "NHS_Gateway2="
if "%~3"=="" goto SetRoutes
if "%~4"=="" goto SetRoutes
rem IPv4 address with netmask and router address defined for network 2.
set "NHS_Network2=%~3"
set "NHS_Router2=%~4"
rem Set the gateway addresses if defined as fifth and sixth parameter.
if not "%~5"=="" set "NHS_Gateway1=%~5"
if not "%~6"=="" set "NHS_Gateway2=%~6"
:SetRoutes
rem The variables NHS_Network1 and NHS_Router1 are always defined.
%SystemRoot%\System32\route.exe delete %NHS_Network1%
%SystemRoot%\System32\route.exe add %NHS_Network1% %NHS_Router1%
if errorlevel 1 (
echo ERROR : Impossible to add route for network 1, please check route print.
) else (
echo Route for network 1 added.
)
rem NHS_Router2 is always defined if NHS_Network2 is defined.
if defined NHS_Network2 (
%SystemRoot%\System32\route.exe delete %NHS_Network2%
%SystemRoot%\System32\route.exe add %NHS_Network2% %NHS_Router2%
if errorlevel 1 (
echo ERROR : Impossible to add route for network 2, please check route print.
) else (
echo Route for network 2 added.
)
)
if defined NHS_Gateway1 (
%SystemRoot%\System32\route.exe delete 0.0.0.0/0
%SystemRoot%\System32\route.exe add 0.0.0.0/0 %NHS_Gateway1% metric 10
if errorlevel 1 (
echo ERROR : Impossible to add route for gateway 1, please check route print.
) else (
echo Route for gateway 1 added.
)
)
if defined NHS_Gateway2 (
%SystemRoot%\System32\route.exe add 0.0.0.0/0 %NHS_Gateway2% metric 20
if errorlevel 1 (
echo ERROR : Impossible to add route for gateway 2, please check route print.
) else (
echo Route for gateway 2 added.
)
)
endlocal
See also the Microsoft support article Testing for a Specific Error Level in Batch Files.
The usage of if errorlevel 1
- meaning if exit code of previous command or application is greater or equal 1 - is better than using %ERRORLEVEL%
within a block as command processor replaces %ERRORLEVEL%
already on parsing the block by current value of this variable before the line above is executed at all. It would be necessary to use delayed expansion if not using special syntax for checking on error level.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
if /?
rem /?
route /?
set /?
setlocal /?
Upvotes: 1