批处理:检查批处理文件中的命令行参数

时间:2014-09-26 13:11:55

标签: loops batch-file parameters cmd

我想在DOS批处理文件中执行一些操作,具体取决于传入的命令行参数 应使用任意数量的参数调用批处理。可能的参数应为(在最好的情况下可扩展):

UPDATE [-verbose [outputFileName]] [-validate] [/?]

此外,应该可以按任何顺序输入参数。 特别是param -verbose 是有意义的:如果给出这个参数,则参数' parameterParam'必须是outputfilename的名称或可以为空。请注意,参数具有前导" - "。参数参数的参数没有前导" - "。
例如:

UPDATE -verbose -validate

将在STDOUT(-verbose)上显示执行步骤并验证输入。

UPDATE -verbose outputFileName.txt -validate

应将执行步骤记录到名为< outputFilename.txt>的文件中。 (-verbose outputFileName.txt)并验证输入。

UPDATE -validate

只会验证输入。

UPDATE -validate -verbose

应与

相同
UPDATE -verbose -validate

UPDATE /?

将显示如何使用update.bat

我该怎么做?使用FOR循环迭代命令行参数?但是怎么样?我可以遍历参数,但如果找到-verbose,我如何预览以下参数以检查是否提供了文件名?

根据提供的参数,应该执行特定操作(启动另一批...) 我想通过java调用LiquiBase:

验证:

java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-update.xml --logLevel=info validate
java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-views-and-sp.xml --logLevel=info validate

对于离线SQL生成:

java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-update.xml --logLevel=info updateSQL > update_%_outputfilename%
java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-views-and-sp.xml --logLevel=info updateSQL  > viewsAndSP_%_outputfilename%

2 个答案:

答案 0 :(得分:1)

@echo off

setlocal enableDelayedExpansion
set "_verbose=no"
set "_validate=no"
set "_outputfilename="
rem set "arg_counter=0"
set "_check_next=no"

if "%~1" equ "/?" call :help

for %%a in (%*) do (


    if "!_check_next!" equ "yes" (
        set "_check_next=no"
        set "arg=%%~a"

        if "!arg:~0,1!" neq "-" (
            set "_outputfilename=%%~a"
        ) else (
           if "%%~a" equ "-validate" (
               set "_validate=yes"
            )
        )
    )

    rem if "%%~a" equ "/?" call :help

    if "%%~a" equ "-verbose" (
        set "_check_next=yes"
        set "_verbose=yes"
    )

    if "%%~a" equ "-validate" (
        set "_validate=yes"
    )

)

echo --%_validate%--%_verbose%--%_outputfilename%--

endlocal
exit /b 0

:help

    echo %~0 [-verbose [outputFileName]] [-validate] [/?]
    echo some explanations

exit /b 0

参数的顺序不是必需的。不确定可扩展性如何,但arg检查代码在“严肃”的编程语言中总是很冗长。

答案 1 :(得分:1)

我终于明白了。这是我的解决方案,基于npocmaka的有用代码:

call _set-env.bat

@echo off

setlocal enableDelayedExpansion
set argC=0
for %%x in (%*) do Set /A argC+=1

set "_verbose=no"
set "_validate=no"
set "_outputfilename="
set "_check_next=no"
set "_sandbox=no"

if "%~1" equ "/?" goto :help

if %argC% == 1 (
    if "%~1" equ "-sandbox" (
        echo.
        echo Running UPDATE with just -sandbox option does not do anything.
        echo Run UPDATE /? for usage.
        :: call :help
        goto :eof
    )
)

for %%a in (%*) do (

    if "!_check_next!" equ "yes" (
        set "_check_next=no"
        set "arg=%%~a"

        if "!arg:~0,1!" neq "-" (
            set "_outputfilename=%%~a"
        ) else (
           if "%%~a" equ "-validate" (
               set "_validate=yes"
            )
        )
    )

    if "%%~a" equ "-verbose" (
        set "_check_next=yes"
        set "_verbose=yes"
    )

    if "%%~a" equ "-validate" (
        set "_validate=yes"
    )

    if "%%~a" equ "-sandbox" (
        set "_sandbox=yes"
    )
)

if %_validate% equ yes (
    call :validateUpdate
    echo !errorlevel!
    if !errorlevel! neq 0 exit /b !errorlevel!
)
if "yes" equ "%_verbose%" (
    if "%_outputfilename%" neq "" (
        call :verboseUpdateToFile
    ) else (
        call :verboseUpdate
    )
    if !errorlevel! neq 0 exit /b !errorlevel!
)
if "no" equ "%_sandbox%" (
    call :update
)

:: echo --%_validate%--%_verbose%--%_outputfilename%--
exit /b 0

:help
    ::echo %~0 [-verbose [outputFileName]] [-validate] [/?]
    @echo Executes LiquiBase changesets to take effect on the database.
    @echo.
    @echo UPDATE [-verbose [outputFileName]] [-validate] [/?]
    @echo.  /?              Shows this help.
    @echo   -validate       Validates the changesets without executing them.
    @echo   -verbose        Prints output of the generated SQL without executing them
    @echo.
    goto :eof

:validateUpdate
    java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-update.xml --logLevel=info validate
    :: java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-views-and-sp.xml --logLevel=info validate
    goto :eof

:verboseUpdate
    java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-update.xml --logLevel=info updateSQL
    java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-views-and-sp.xml --logLevel=info updateSQL
    goto :eof

:verboseUpdateToFile
    java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-update.xml --logLevel=info updateSQL > update_"%_outputfilename%"
    java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-views-and-sp.xml --logLevel=info updateSQL  > viewsAndSP_"%_outputfilename%"
    goto :eof

:update
@echo update...
rem java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-update.xml --logLevel=info update
rem java -jar %LIQUIBASE_EXEC% --changeLogFile=../changesets/changelog-views-and-sp.xml --logLevel=info update

endlocal
exit /b 0

有一件事仍不清楚: 让我们说:执行validateUpdate并发生验证错误,LiquiBase打印出" Liquibase'验证'成功" 和ERRORLEVEL是0.这是因为LiquiBase打印出验证错误,但是自己退出0,因此ERRORLEVEL是0? 这意味着我无论如何都无法处理此类验证错误。 我打算在标签处运行代码:仅在没有错误发生时更新。