Guillaumedk
Guillaumedk

Reputation: 35

How to correctly check the presence of parameters in batch?

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:

So ... 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

Answers (2)

Magoo
Magoo

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

Mofi
Mofi

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

Related Questions