如何正确检查批处理中是否存在参数?

时间:2015-12-24 00:12:48

标签: batch-file arguments

我现在尝试将一个简单的网络脚本批量处理3个小时,但我仍然坚持检查参数。

我实际上使用

IF not "%~1"=="" ( IF not "%~2"=="" (
    Set NHS_Network1 = %1
    Set NHS_Router1  = %2
))

并且在执行时仍会出现语法错误。

这是我已经尝试过的:

  • IF DEFINED:不适用于参数
  • IF [%1]NEQ[] ( IF [%2]NEQ[] ( ... ))导致错误(意外

所以......我现在很困惑。我从未批量做过“复杂”的事情,但我熟悉bash,C,C ++,Java,......

可能有一些错误的完整代码,因为我一开始就陷入了困境。

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)
)

2 个答案:

答案 0 :(得分:1)

请阅读Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案,以获得解释为什么在批处理文件中通常没有好主意在等号上放置一个或多个空格,以便为环境变量分配字符串。

阅读this answer,解释批处理文件中 IF 条件的正确语法。必须谨慎使用批处理文件中的空格。在某些位置需要一个空间,在其他位置,空间通常是错误的。

必须注意引用由( ... )定义的块中的环境变量的值,因为命令处理器使用%variable%语法替换所有对环境变量的引用在处理块中的行之前,它们在整个块中的值。对于在块中定义或设置的环境变量以及在块内进行评估,必须启用延迟扩展并使用!variable!引用这些变量以使用延迟扩展。更好的是避免延迟环境变量扩展的需要。

goto 是C / C ++中很少使用的关键字。但是在批处理文件中,它是一个非常重要的命令,它的使用使得大多数批处理文件比使用C / C ++中使用的嵌套 IF 结构更容易,以避免使用 goto 。 / p>

评估批处理文件的参数有一般规则:

如果未定义第一个参数,则肯定没有更多参数。

嗯,可以使用例如"" "second parameter" ThirdParameter来调用批处理文件以使用3个参数运行它,其中第一个是空字符串。但对于您的脚本,可以将空字符串解释为未指定参数。

以下是使用转到重新编码的批处理文件,并且无需延迟扩展。

@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

另请参阅Microsoft支持文章Testing for a Specific Error Level in Batch Files

使用if errorlevel 1 - 意味着如果前一个命令或应用程序的退出代码大于或等于1 - 比使用%ERRORLEVEL%更好,因为命令处理器已经取代%ERRORLEVEL%在执行上面的行之前,通过此变量的当前值解析块。如果不使用特殊语法来检查错误级别,则有必要使用延迟扩展。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • if /?
  • rem /?
  • route /?
  • set /?
  • setlocal /?

答案 1 :(得分:0)

@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

如果需要,可以添加其他数据 - 格式应该很明显。

args设置为提供给批次的参数列表。

使用每个varname:varvalue,将%%v分配给变量名,并将%%w分配为默认值。

将变量设置为第一个剩余参数或默认

如果有剩余参数,请删除一个。否则,请使用默认值。

与原版不完全相同,但可能有用。