【问题标题】:Batch: checking commandline parameters in batch file批处理:检查批处理文件中的命令行参数
【发布时间】:2014-09-26 13:11:54
【问题描述】:

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

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

此外,应该可以按任何顺序输入参数。 特别是参数 -verbose 很有趣:如果给定此参数,则以下 'parameterParam' 必须是输出文件名的名称或可以为空。请注意,参数有一个前导“-”。形参实参的形参没有前导“-”。
例如:

UPDATE -verbose -validate

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

UPDATE -verbose outputFileName.txt -validate

应将执行步骤记录到名为 (-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%

【问题讨论】:

  • 真的使用 DOS 吗?还是cmd.exe
  • 我有一个名为 update.bat 的文件,我想让它在命令行工具中运行在 Windows 机器上。
  • 那就是cmd.exe,我去换标签。
  • 这不是一个好的设计,因为文件名可以以- 开头。您应该添加一个带有所需文件名参数的附加 -output 选项:UPDATE [-verbose] [-validate] [-output outFile]
  • 看看stackoverflow.com/a/8162578/1012053。它可以满足您的大部分需求,除了您需要我之前评论中的-output outFile 选项,并且帮助选项将是-? 而不是/?

标签: loops batch-file parameters cmd


【解决方案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 检查代码也总是很冗长。

【讨论】:

  • 这样我可以收到关于 ECHO 的消息... ECHO [ON |离开]。我该如何防止这种情况?您的解决方案填充了一些变量。我该如何使用它们?我想根据参数调用相应的程序。我可以在循环中调用像 :prog1 这样的标签,并且在执行后循环继续吗?或者我是否必须在循环检查变量值并启动程序之后放置一些 IF?它对我不起作用。
  • @du-it 我无法根据参数知道您要调用哪些程序,因为未提供此信息。是的,最好检查变量并调用您想要的程序.更好地提供更多信息,因为您的问题范围仅涉及 agruments 解析
  • 请参阅我的扩展问题。在没有任何命令行命令的情况下运行 java 命令。
【解决方案2】:

我终于明白了。这是我基于 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 'validate'success" 并且 ERRORLEVEL 为 0。这是因为 LiquiBase 打印出发生了验证错误但自行退出0,因此 ERRORLEVEL 为 0? 这意味着无论如何我都无法处理此类验证错误。 我打算在标签上运行代码:仅在没有错误发生时才更新。

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2019-08-30
    • 2011-03-28
    相关资源
    最近更新 更多