2014-09-26 163 views
1

我想根据传入的命令行参数在DOS批处理文件中执行一些操作。
该批次应使用任意数量的参数进行调用。可能的参数应为(在最好的情况下可扩展):批处理:检查批处理文件中的命令行参数

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

此外,它应该可以以任意顺序进入PARAMS。 尤其是参数-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

你是否正在使用DOS?或'cmd.exe'? – paxdiablo 2014-09-26 13:13:23

+0

我有一个名为update.bat的文件,我想让它在命令行工具中的Windows机器上运行。 – 2014-09-26 13:20:16

+0

然后,这将是'cmd.exe',我会更改标签。 – paxdiablo 2014-09-26 13:26:53

回答

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检查代码也总是冗长。

+0

这样我得到有关ECHO的消息... ECHO [ON | OFF]。我怎样才能防止呢? 您的解决方案填充了一些变量。我如何使用它们?我想根据参数调用相应的程序。我可以在循环内调用像prog1这样的标签吗?执行后循环会继续吗?或者我必须在循环检查变量值并启动程序之后放置一些IF?它不适合我。 – 2014-09-26 17:29:37

+0

@ du-it因为没有提供这些信息,所以我无法知道要调用哪些程序,具体取决于参数。最好是检查变量并调用所需的程序。 Betrer提供更多信息,因为您的问题范围仅涉及解析 – npocmaka 2014-09-26 17:43:35

+0

请参阅我的扩展问题。在没有任何命令行命令的情况下运行java命令就可以工作。 – 2014-09-26 18:10:27

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? 这意味着我无法处理这种验证错误。 我打算在标签上运行代码:仅在没有错误发生时更新。