How can I check if an argument is defined when starting/calling a batch file?

后端 未结 7 1810
无人共我
无人共我 2020-12-13 03:21

I\'m trying to use the following validation logic in a batch file but the \"usage\" block never executes even when no parameter is supplied to the batch file.



        
相关标签:
7条回答
  • 2020-12-13 03:45

    The check for whether a commandline argument has been set can be [%1]==[], but, as Dave Costa points out, "%1"=="" will also work.

    I also fixed a syntax error in the usage echo to escape the greater-than and less-than signs. In addition, the exit needs a /B argument otherwise CMD.exe will quit.

    @echo off
    
    if [%1]==[] goto usage
    @echo This should not execute
    @echo Done.
    goto :eof
    :usage
    @echo Usage: %0 ^<EnvironmentName^>
    exit /B 1
    
    0 讨论(0)
  • 2020-12-13 03:53

    This is the same as the other answers, but uses only one label and puts the usage first, which additionally makes it serve as a kind of documentation commend of the script which is also usually placed at the top:

    @echo off
    :: add other test for the arguments here...
    if not [%1]==[] goto main
    :: --------------------------
    echo This command does something.
    echo.
    echo %0 param%%1 param%%2
    echo       param%%1 the file to operate on
    echo       param%%1 another file
    
    :: --------------------------
    exit /B 1
    
    :main
    :: --------------------------
    echo do something with all arguments (%%* == %*) here...
    

    However, if you don't have to use cmd/batch, use bash on WSL or powershell, they have more sane syntax and less arcane features.

    0 讨论(0)
  • 2020-12-13 03:54

    Get rid of the parentheses.

    Sample batch file:

    echo "%1"
    
    if ("%1"=="") echo match1
    
    if "%1"=="" echo match2
    

    Output from running above script:

    C:\>echo "" 
    ""
    
    C:\>if ("" == "") echo match1 
    
    C:\>if "" == "" echo match2 
    match2
    

    I think it is actually taking the parentheses to be part of the strings and they are being compared.

    0 讨论(0)
  • 2020-12-13 03:57

    IF "%1"=="" will fail, all versions of this will fail under certain poison character conditions. Only IF DEFINED or IF NOT DEFINED are safe

    0 讨论(0)
  • 2020-12-13 04:00
    IF "%~1"=="" GOTO :Usage
    

    ~ will de-quote %1 if %1 itself is quoted.

    " " will protect from special characters passed. for example calling the script with &ping

    0 讨论(0)
  • 2020-12-13 04:03

    A more-advanced example:

    ⍟ unlimited arguments.

    ⍟ exist on file system (either file or directory?) or a generic string.

    ⍟ specify if is a file

    ⍟ specify is a directory

    no extensions, would work in legacy scripts!

    minimal code ☺

    @echo off
    
    :loop
          ::-------------------------- has argument ?
          if ["%~1"]==[""] (
            echo done.
            goto end
          )
          ::-------------------------- argument exist ?
          if not exist %~s1 (
            echo not exist
          ) else (
            echo exist
            if exist %~s1\NUL (
              echo is a directory
            ) else (
              echo is a file
            )
          )
          ::--------------------------
          shift
          goto loop
          
          
    :end
    
    pause
    

    ✨ other stuff..✨

    ■ in %~1 - the ~ removes any wrapping " or '.

    ■ in %~s1 - the s makes the path be DOS 8.3 naming, which is a nice trick to avoid spaces in file-name while checking stuff (and this way no need to wrap the resource with more "s.

    ■ the ["%~1"]==[""] "can not be sure" if the argument is a file/directory or just a generic string yet, so instead the expression uses brackets and the original unmodified %1 (just without the " wrapping, if any..)

    if there were no arguments of if we've used shift and the arg-list pointer has passed the last one, the expression will be evaluated to [""]==[""].

    ■ this is as much specific you can be without using more tricks (it would work even in windows-95's batch-scripts...)

    ■ execution examples

    save it as identifier.cmd

    it can identify an unlimited arguments (normally you are limited to %1-%9), just remember to wrap the arguments with inverted-commas, or use 8.3 naming, or drag&drop them over (it automatically does either of above).


    this allows you to run the following commands:

    identifier.cmd c:\windows and to get

    exist
    is a directory
    done
    

    identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" and to get

    exist
    is a file
    done
    

    ⓷ and multiple arguments (of course this is the whole-deal..)

    identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

    and to get

    exist
    is a directory
    exist
    is a file
    exist
    is a file
    not exist
    done.
    

    naturally it can be a lot more complex, but nice examples should always be simple and minimal. :)

    Hope it helps anyone :)

    published here:CMD Ninja - Unlimited Arguments Processing, Identifying If Exist In File-System, Identifying If File Or Directory

    and here is a working example that takes any amount of APK files (Android apps) and installs them on your device via debug-console (ADB.exe): Make The Previous Post A Mass APK Installer That Does Not Uses ADB Install-Multi Syntax

    0 讨论(0)
提交回复
热议问题