How can I pass arguments to a batch file?

后端 未结 18 2139
陌清茗
陌清茗 2020-11-22 02:53

I need to pass an ID and a password to a batch file at the time of running rather than hardcoding them into the file.

Here\'s what the command line looks like:

18条回答
  •  一向
    一向 (楼主)
    2020-11-22 03:14

    Inspired by an answer elsewhere by @Jon, I have crafted a more general algorithm for extracting named parameters, optional values, and switches.

    Let us say that we want to implement a utility foobar. It requires an initial command. It has an optional parameter --foo which takes an optional value (which cannot be another parameter, of course); if the value is missing it defaults to default. It also has an optional parameter --bar which takes a required value. Lastly it can take a flag --baz with no value allowed. Oh, and these parameters can come in any order.

    In other words, it looks like this:

    foobar  [--foo []] [--bar ] [--baz]
    

    Here is a solution:

    @ECHO OFF
    SETLOCAL
    REM FooBar parameter demo
    REM By Garret Wilson
    
    SET CMD=%~1
    
    IF "%CMD%" == "" (
      GOTO usage
    )
    SET FOO=
    SET DEFAULT_FOO=default
    SET BAR=
    SET BAZ=
    
    SHIFT
    :args
    SET PARAM=%~1
    SET ARG=%~2
    IF "%PARAM%" == "--foo" (
      SHIFT
      IF NOT "%ARG%" == "" (
        IF NOT "%ARG:~0,2%" == "--" (
          SET FOO=%ARG%
          SHIFT
        ) ELSE (
          SET FOO=%DEFAULT_FOO%
        )
      ) ELSE (
        SET FOO=%DEFAULT_FOO%
      )
    ) ELSE IF "%PARAM%" == "--bar" (
      SHIFT
      IF NOT "%ARG%" == "" (
        SET BAR=%ARG%
        SHIFT
      ) ELSE (
        ECHO Missing bar value. 1>&2
        ECHO:
        GOTO usage
      )
    ) ELSE IF "%PARAM%" == "--baz" (
      SHIFT
      SET BAZ=true
    ) ELSE IF "%PARAM%" == "" (
      GOTO endargs
    ) ELSE (
      ECHO Unrecognized option %1. 1>&2
      ECHO:
      GOTO usage
    )
    GOTO args
    :endargs
    
    ECHO Command: %CMD%
    IF NOT "%FOO%" == "" (
      ECHO Foo: %FOO%
    )
    IF NOT "%BAR%" == "" (
      ECHO Bar: %BAR%
    )
    IF "%BAZ%" == "true" (
      ECHO Baz
    )
    
    REM TODO do something with FOO, BAR, and/or BAZ
    GOTO :eof
    
    :usage
    ECHO FooBar
    ECHO Usage: foobar ^ [--foo [^]] [--bar ^] [--baz]
    EXIT /B 1
    
    • Use SETLOCAL so that the variables don't escape into the calling environment.
    • Don't forget to initialize the variables SET FOO=, etc. in case someone defined them in the calling environment.
    • Use %~1 to remove quotes.
    • Use IF "%ARG%" == "" and not IF [%ARG%] == [] because [ and ] don't play will at all with values ending in a space.
    • Even if you SHIFT inside an IF block, the current args such as %~1 don't get updated because they are determined when the IF is parsed. You could use %~1 and %~2 inside the IF block, but it would be confusing because you had a SHIFT. You could put the SHIFT at the end of the block for clarity, but that might get lost and/or confuse people as well. So "capturing" %~1 and %~1 outside the block seems best.
    • You don't want to use a parameter in place of another parameter's optional value, so you have to check IF NOT "%ARG:~0,2%" == "--".
    • Be careful only to SHIFT when you use one of the parameters.
    • The duplicate code SET FOO=%DEFAULT_FOO% is regrettable, but the alternative would be to add an IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% outside the IF NOT "%ARG%" == "" block. However because this is still inside the IF "%PARAM%" == "--foo" block, the %FOO% value would have been evaluated and set before you ever entered the block, so you would never detect that both the --foo parameter was present and also that the %FOO% value was missing.
    • Note that ECHO Missing bar value. 1>&2 sends the error message to stderr.
    • Want a blank line in a Windows batch file? You gotta use ECHO: or one of the variations.

提交回复
热议问题