Comment passer des parameters de ligne de commande à un fichier de commandes?

Je dois transmettre l’identifiant et le mot de passe à un fichier cmd (ou chauve-souris) au moment de l’exécution plutôt que de les coder en dur dans le fichier.

Voici à quoi ressemble la ligne de commande:

test.cmd admin P@55w0rd > test-log.txt 

    Une autre astuce utile est d’utiliser %* pour signifier “tout”. Par exemple:

     echo off set arg1=%1 set arg2=%2 shift shift fake-command /u %arg1% /p %arg2% %* 

    Lorsque vous courez:

     test-command admin password foo bar 

    le fichier de commandes ci-dessus s’exécutera:

     fake-command /u admin /p password foo bar 

    Je peux avoir la syntaxe légèrement fausse, mais c’est l’idée générale.

    Voici comment je le fais.

     @fake-command /u %1 /p %2 

    Voici à quoi ressemble la ligne de commande:

     test.cmd admin P@55w0rd > test-log.txt 

    Le% 1 s’applique au premier paramètre, le% 2 (et voici la partie délicate) s’applique au second. Vous pouvez avoir jusqu’à 9 parameters passés de cette manière.

    Si vous voulez gérer intelligemment les parameters manquants, vous pouvez faire quelque chose comme:

     IF %1.==. GOTO No1 IF %2.==. GOTO No2 ... do stuff... GOTO End1 :No1 ECHO No param 1 GOTO End1 :No2 ECHO No param 2 GOTO End1 :End1 

    L’access aux parameters de lot peut être simple avec% 1,% 2, …% 9 ou% *,
    mais seulement si le contenu est simple.

    Il n’y a pas de moyen simple pour des contenus complexes comme "&"^& , car il n’est pas possible d’accéder à% 1 sans générer d’erreur.

     set var=%1 set "var=%1" set var=%~1 set "var=%~1" 

    Les lignes s’étendent à

     set var="&"& set "var="&"&" set var="&"& set "var="&"&" 

    Et chaque ligne échoue, car l’un des & est en dehors des guillemets.

    Il peut être résolu en lisant un fichier temporaire une version remarquée du paramètre.

     @echo off SETLOCAL DisableDelayedExpansion SETLOCAL for %%a in (1) do ( set "prompt=" echo on for %%b in (1) do rem * #%1# @echo off ) > param.txt ENDLOCAL for /F "delims=" %%L in (param.txt) do ( set "param1=%%L" ) SETLOCAL EnableDelayedExpansion set "param1=!param1:*#=!" set "param1=!param1:~0,-2!" echo %%1 is '!param1!' 

    L’astuce consiste à activer l’ echo on et à développer le% 1 après une instruction rem (fonctionne également avec %2 .. %* ).
    Ainsi, même "&"& pourrait être répercuté sans produire d’erreur, comme on le fait remarquer.

    Mais pour pouvoir redirect la sortie de l’ echo on , vous avez besoin des deux boucles for.

    Les caractères supplémentaires * # sont utilisés pour éviter les contenus tels que /? (montrerait l’aide pour REM ).
    Ou un caret à la fin de la ligne pourrait fonctionner comme un caractère multiligne, même après un rem .

    Ensuite, lisez le paramètre de sortie de sortie du fichier, mais soigneusement.
    Le FOR / F devrait fonctionner avec l’extension retardée, sinon le contenu avec “!” serait détruit.
    Après avoir supprimé les caractères supplémentaires dans param1 , vous l’avez compris.

    Et pour utiliser param1 en toute sécurité, activez l’extension retardée.

    Oui, et n’oubliez pas d’utiliser des variables comme %%1 lors de l’utilisation de if et for et du gang.

    Si vous oubliez le double % , vous substituerez des arguments de ligne de commande (éventuellement nuls) et vous recevrez des messages d’erreur assez confus.

    Il n’y a pas besoin de le compliquer. C’est simplement la commande% 1% 2 parameters, par exemple,

     @echo off xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z echo copied %1 to %2 pause 

    La “pause” affiche ce que le fichier de commandes a fait et attend que vous appuyiez sur la touche ANY. Enregistrez-le sous xx.bat dans le dossier Windows.

    Pour l’utiliser, tapez, par exemple:

     xx c:\f\30\*.* f:\sites\30 

    Ce fichier de commandes prend en charge tous les parameters nécessaires, tels que la copie de fichiers uniquement, qui sont plus récents, etc. Je l’ai utilisé avant Windows. Si vous souhaitez voir les noms des fichiers en cours de copie, ne spécifiez pas le paramètre Q

     @ECHO OFF :Loop IF "%1"=="" GOTO Continue SHIFT GOTO Loop :Continue 

    Remarque: SI "%1"=="" posera des problèmes si %1 est entre guillemets.

    Dans ce cas, utilisez IF [%1]==[] ou, dans NT 4 (SP6) et versions ultérieures uniquement, IF "%~1"=="" place.

    Un ami me posait des questions sur ce sujet récemment, alors je pensais que je publierais comment je gère les arguments de ligne de commande dans les fichiers de commandes.

    Cette technique a un peu de surcharge, comme vous le verrez, mais elle rend mes fichiers batch très faciles à comprendre et à mettre en œuvre rapidement. En plus de soutenir les structures suivantes:

     >template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...] 

    La jiste de cela est d’avoir les fonctions :init :parse et :main .

    Exemple d’utilisation

     >template.bat /? test v1.23 This is a sample batch file template, providing command-line arguments and flags. USAGE: test.bat [flags] "required argument" "optional argument" /?, --help shows this help /v, --version shows the version /e, --verbose shows detailed output -f, --flag value specifies a named parameter value >template.bat <- throws missing argument error (same as /?, plus..) **** **** **** MISSING "REQUIRED ARGUMENT" **** **** **** >template.bat -v 1.23 >template.bat --version test v1.23 This is a sample batch file template, providing command-line arguments and flags. >template.bat -e arg1 **** DEBUG IS ON UnNamedArgument: "arg1" UnNamedOptionalArg: not provided NamedFlag: not provided >template.bat --flag "my flag" arg1 arg2 UnNamedArgument: "arg1" UnNamedOptionalArg: "arg2" NamedFlag: "my flag" >template.bat --verbose "argument #1" --flag "my flag" second **** DEBUG IS ON UnNamedArgument: "argument #1" UnNamedOptionalArg: "second" NamedFlag: "my flag" 

    template.bat

     @::!/dos/rocks @echo off goto :init :header echo %__NAME% v%__VERSION% echo This is a sample batch file template, echo providing command-line arguments and flags. echo. goto :eof :usage echo USAGE: echo %__BAT_NAME% [flags] "required argument" "optional argument" echo. echo. /?, --help shows this help echo. /v, --version shows the version echo. /e, --verbose shows detailed output echo. -f, --flag value specifies a named parameter value goto :eof :version if "%~1"=="full" call :header & goto :eof echo %__VERSION% goto :eof :missing_argument call :header call :usage echo. echo **** **** echo **** MISSING "REQUIRED ARGUMENT" **** echo **** **** echo. goto :eof :init set "__NAME=%~n0" set "__VERSION=1.23" set "__YEAR=2017" set "__BAT_FILE=%~0" set "__BAT_PATH=%~dp0" set "__BAT_NAME=%~nx0" set "OptHelp=" set "OptVersion=" set "OptVerbose=" set "UnNamedArgument=" set "UnNamedOptionalArg=" set "NamedFlag=" :parse if "%~1"=="" goto :validate if /i "%~1"=="/?" call :header & call :usage "%~2" & goto :end if /i "%~1"=="-?" call :header & call :usage "%~2" & goto :end if /i "%~1"=="--help" call :header & call :usage "%~2" & goto :end if /i "%~1"=="/v" call :version & goto :end if /i "%~1"=="-v" call :version & goto :end if /i "%~1"=="--version" call :version full & goto :end if /i "%~1"=="/e" set "OptVerbose=yes" & shift & goto :parse if /i "%~1"=="-e" set "OptVerbose=yes" & shift & goto :parse if /i "%~1"=="--verbose" set "OptVerbose=yes" & shift & goto :parse if /i "%~1"=="--flag" set "NamedFlag=%~2" & shift & shift & goto :parse if not defined UnNamedArgument set "UnNamedArgument=%~1" & shift & goto :parse if not defined UnNamedOptionalArg set "UnNamedOptionalArg=%~1" & shift & goto :parse shift goto :parse :validate if not defined UnNamedArgument call :missing_argument & goto :end :main if defined OptVerbose ( echo **** DEBUG IS ON ) echo UnNamedArgument: "%UnNamedArgument%" if defined UnNamedOptionalArg echo UnNamedOptionalArg: "%UnNamedOptionalArg%" if not defined UnNamedOptionalArg echo UnNamedOptionalArg: not provided if defined NamedFlag echo NamedFlag: "%NamedFlag%" if not defined NamedFlag echo NamedFlag: not provided :end call :cleanup exit /B :cleanup REM The cleanup function is only really necessary if you REM are _not_ using SETLOCAL. set "__NAME=" set "__VERSION=" set "__YEAR=" set "__BAT_FILE=" set "__BAT_PATH=" set "__BAT_NAME=" set "OptHelp=" set "OptVersion=" set "OptVerbose=" set "UnNamedArgument=" set "UnNamedArgument2=" set "NamedFlag=" goto :eof 

    Gardons cela simple.

    Voici le fichier .cmd.

     @echo off rem this file is named echo_3params.cmd echo %1 echo %2 echo %3 set v1=%1 set v2=%2 set v3=%3 echo v1 equals %v1% echo v2 equals %v2% echo v3 equals %v3% 

    Voici 3 appels de la ligne de commande.

     C:\Users\joeco>echo_3params 1abc 2 def 3 ghi 1abc 2 def v1 equals 1abc v2 equals 2 v3 equals def C:\Users\joeco>echo_3params 1abc "2 def" "3 ghi" 1abc "2 def" "3 ghi" v1 equals 1abc v2 equals "2 def" v3 equals "3 ghi" C:\Users\joeco>echo_3params 1abc '2 def' "3 ghi" 1abc '2 def' v1 equals 1abc v2 equals '2 v3 equals def' C:\Users\joeco> 
     FOR %%A IN (%*) DO ( REM Now your batch file handles %%A instead of %1 REM No need to use SHIFT anymore. ECHO %%A ) 

    Cela boucle sur les parameters du lot (% *), qu’ils soient ou non cités, puis fait écho à chaque paramètre.

    J’ai écrit un simple script read_params qui peut être appelé en tant que fonction (ou .bat externe) et mettra toutes les variables dans l’environnement actuel. Il ne modifiera pas les parameters d’origine car la fonction est call avec une copie des parameters d’origine.

    Par exemple, donnez la commande suivante:

     myscript.bat some -random=43 extra -greeting="hello world" fluff 

    myscript.bat pourrait utiliser les variables après avoir appelé la fonction:

     call :read_params %* echo %random% echo %greeting% 

    Voici la fonction:

     :read_params if not %1/==/ ( if not "%__var%"=="" ( if not "%__var:~0,1%"=="-" ( endlocal goto read_params ) endlocal & set %__var:~1%=%~1 ) else ( setlocal & set __var=%~1 ) shift goto read_params ) exit /B 

    Limites

    • Impossible de charger des arguments sans valeur telle que -force . Vous pouvez utiliser -force=true mais je ne peux pas penser à un moyen d’autoriser des valeurs vides sans connaître une liste de parameters à l’avance qui n’auront pas de valeur.

    Changelog

    • 18/02/2016
      • Ne nécessite plus d’expansion retardée
      • Travaille maintenant avec d’autres arguments en ligne de commande en recherchant les parameters - before.

    Pour faire référence à une variable set en ligne de commande, vous devez utiliser “% a%”, par exemple:

      set a=100 echo %a% output = 100 

    Remarque: Cela fonctionne pour Windows 7 pro.

    Créez un nouveau fichier de commandes (exemple: openclass.bat) et écrivez cette ligne dans le fichier:

     java %~n1 

    Ensuite, placez le fichier batch, disons, le dossier system32, allez dans votre fichier de classe Java, faites un clic droit, Propriétés, Ouvrir avec …, puis trouvez votre fichier batch, sélectionnez-le et c’est …

    Ça marche pour moi.

    PS: Je ne peux pas trouver un moyen de fermer la fenêtre cmd lorsque je ferme la classe Java. Pour l’instant…

    Solution simple (même si la question est ancienne)

    Test1.bat

     echo off echo "Batch started" set arg1=%1 echo "arg1 is %arg1%" echo on pause 

    CallTest1.bat

     call "C:\Temp\Test1.bat" pass123 

    sortie

     YourLocalPath>call "C:\Temp\test.bat" pass123 YourLocalPath>echo off "Batch started" "arg1 is pass123" YourLocalPath>pause Press any key to continue . . . 

    Où YourLocalPath est le chemin du répertoire en cours.

    Pour garder les choses simples, stockez la commande param dans la variable et utilisez la variable pour la comparaison.

    Ce n’est pas seulement simple à écrire, mais c’est aussi simple à gérer, donc si plus tard, une autre personne ou vous lisez votre script après une longue période, il sera facile à comprendre et à maintenir.

    Pour écrire du code en ligne: voir les autres réponses.

    Inspiré par une réponse d’ailleurs de @Jon, j’ai conçu un algorithme plus général pour extraire des parameters nommés, des valeurs facultatives et des commutateurs.

    Disons que nous voulons implémenter un utilitaire foobar . Il nécessite une commande initiale. Il a un paramètre optionnel --foo qui prend une valeur facultative (qui ne peut bien sûr pas être un autre paramètre); si la valeur est manquante, elle est définie default défaut sur default . Il a également un paramètre optionnel --bar qui prend une valeur requirejse . Enfin, il peut prendre un drapeau --baz sans valeur autorisée. Oh, et ces parameters peuvent venir dans n’importe quel ordre.

    En d’autres termes, cela ressemble à ceci:

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

    Voici une 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 
    • Utilisez SETLOCAL pour que les variables ne s’échappent pas dans l’environnement appelant.
    • N’oubliez pas d’initialiser les variables SET FOO= , etc. au cas où quelqu’un les définirait dans l’environnement appelant.
    • Utilisez %~1 pour supprimer les guillemets.
    • Utilisez IF "%ARG%" == "" et non IF [%ARG%] == [] car [ et ] ne jouent pas du tout avec des valeurs se terminant par un espace.
    • Même si vous SHIFT intérieur d’un bloc IF , les arguments actuels tels que %~1 ne sont pas mis à jour car ils sont déterminés lors de l’ IF syntaxique du stream d’information. Vous pouvez utiliser %~1 et %~2 dans le bloc IF , mais cela peut être déroutant car vous avez un SHIFT . Vous pouvez mettre le SHIFT à la fin du bloc pour plus de clarté, mais cela pourrait être perdu et / ou confondre les gens. Donc, “capturer” %~1 et %~1 dehors du bloc semble mieux.
    • Vous ne voulez pas utiliser un paramètre à la place de la valeur facultative d’un autre paramètre, vous devez donc vérifier IF NOT "%ARG:~0,2%" == "--" .
    • Faites attention à SHIFT uniquement lorsque vous utilisez l’ un des parameters.
    • Le code dupliqué SET FOO=%DEFAULT_FOO% est regrettable, mais l’alternative serait d’append un IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% dehors du IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% IF NOT "%ARG%" == "" . Cependant, comme il se trouve toujours dans le bloc IF "%PARAM%" == "--foo" , la valeur %FOO% aurait été évaluée et définie avant que vous ayez entré le bloc, vous ne détecteriez donc jamais que --foo paramètre --foo était présent et que la valeur %FOO% était manquante.
    • Notez que la ECHO Missing bar value. 1>&2 ECHO Missing bar value. 1>&2 envoie le message d’erreur à stderr.
    • Vous voulez une ligne vierge dans un fichier de commandes Windows? Vous devez utiliser ECHO: ou l’une des variantes.