Comment puis-je passer des paramètres de ligne de commande à un fichier batch?

J'ai besoin de passer l'id et le mot de passe à un fichier cmd (ou bat) 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
942
demandé sur Peter Mortensen 2008-08-25 22:14:18

15 réponses

Une Autre astuce utile est d'utiliser %* pour dire "tous". Par exemple:

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

Lorsque vous exécutez:

test-command admin password foo bar

Le fichier batch ci-dessus s'exécutera:

fake-command /u admin /p password foo bar

J'ai peut-être la syntaxe un peu mal, mais c'est l'idée générale.

836
répondu Greg Hewgill 2018-07-04 16:54:25

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 paramètres passés de cette façon.

235
répondu Keng 2014-01-07 19:54:13

Si vous voulez gérer intelligemment les paramètres 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
123
répondu thelsdj 2008-08-25 20:03:34

L'accès aux paramètres de lot peut être simple avec %1, %2, ... %9 ou aussi %*,
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 une 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 à partir d'un fichier temporaire une versionremarqué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 echo on et à développer le %1 après une instruction rem (fonctionne également avec %2 .. %*).
Ainsi, même "&"& pourrait être repris sans produire d'erreur, comme on le remarque.

Mais pour pouvoir rediriger la sortie du echo on, vous avez besoin des deux boucles for.

, Les caractères supplémentaires * # sont utilisés pour être en sécurité contre des contenus comme /? (montrerait l'aide de REM).
Ou un caret ^ à la fin de la ligne pourrait fonctionner comme une multiligne caractère, même après un rem.

Puis en lisant le paramètre rem sortie du fichier, mais soigneusement.
LE FOR / F devrait fonctionner avec une expansion retardée, sinon le contenu avec"!"serait détruit.
Après avoir supprimé les caractères supplémentaires dans param1, Vous l'avez.

Et pour utiliser param1 de manière sûre, activez l'expansion retardée.

76
répondu jeb 2018-08-09 14:02:58

Oui, et n'oubliez pas d'utiliser des variables comme %%1 lorsque vous utilisez if et for et le gang.

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

53
répondu Frank Krueger 2008-08-25 18:16:32

Il n'y a pas besoin de le compliquer. C'est simplement la commande %1 %2 paramètres, 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 batch a fait et attend que vous frappiez 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 batch prend en charge tous les paramètres nécessaires, comme la copie uniquement des fichiers, qui sont plus récents, etc. Je l'ai utilisé depuis avant Windows. Si vous aimez voir les noms des fichiers, comme ils sont copiés, omettez le paramètre Q.

48
répondu DearWebby 2017-05-16 10:56:05
@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

Remarque: Si {[1] } causera des problèmes si %1 est entre guillemets lui-même.

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

30
répondu rightcodeatrighttime 2016-11-15 12:49:39

Un ami me posait des questions sur ce sujet récemment, alors j'ai pensé poster comment je gère les arguments de ligne de commande dans les fichiers batch.

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

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

Le jist de c'est d'avoir la :init, :parse, et :main fonctions.

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"

Modèle.MTD

@::!/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
23
répondu wasatchwizard 2017-07-13 03:32:46

Restons simples.

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>
18
répondu Love and peace - Joe Codeswell 2015-12-31 19:59:33
FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)

Cette boucle sur les paramètres de lot ( % * ) soit ils sont entre guillemets ou non, puis échos chaque paramètre.

16
répondu Amr Ali 2014-11-25 23:09:12

J'ai écrit un script read_params simple qui peut être appelé en tant que Fonction (Ou Externe .bat) et mettra toutes les variables dans l'environnement actuel. Il ne modifiera pas les paramètres d'origine car la fonction est called avec une copie des paramètres d'origine.

Par exemple, avec la commande suivante:

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

myscript.bat serait capable d'utiliser les variables après avoir appelé la fonction:

call :read_params %*

echo %random%
echo %greeting%

Voici le 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 tels 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 paramètres à l'avance qui n'auront pas de valeur.

Changelog

  • 2/18/2016
    • ne nécessite plus d'expansion retardée
    • fonctionne maintenant avec d'autres arguments de ligne de commande en recherchant - avant de paramètres.
16
répondu Evan Kennedy 2016-02-18 22:29:05

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.

8
répondu CMS_95 2015-11-02 15:20:43

Créer un nouveau fichier batch (exemple: openclass.bat) et écrivez cette ligne dans le fichier:

java %~n1

, Puis placez le fichier batch dans, disons, le dossier system32, allez dans votre fichier de classe Java, clic droit, Propriétés, Ouvrez avec..., puis Trouvez votre fichier batch, sélectionnez-le et c'est tout...

Ça marche pour moi.

PS: Je ne trouve pas de moyen de fermer la fenêtre cmd lorsque je ferme la classe Java. Pour l'instant...

4
répondu SvenVP 2015-10-30 15:56:28

Solution Simple (même si la question Est ancienne)

Essai1.MTD

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

CallTest1.MTD

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 courant.

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

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

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

2
répondu Amol Ramkrishna Patil 2018-07-03 13:48:36

Inspiré par une réponse ailleurs par @Jon, j'ai conçu un algorithme plus général pour extraire les paramètres nommés, les valeurs optionnelles et les commutateurs.

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

En d'autres termes, cela ressemble à ceci:

foobar <command> [--foo [<fooval>]] [--bar <barval>] [--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 ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--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. dans le cas où quelqu'un les a définis dans l'environnement appelant.
  • utilisez %~1 pour supprimer citation.
  • utilisez IF "%ARG%" == "" et non IF [%ARG%] == [] parce que [ et ] ne jouent pas du tout avec des valeurs se terminant dans un espace.
  • même si vous SHIFT à l'intérieur d'un bloc IF, les arguments actuels tels que %~1 ne sont pas mis à jour car ils sont déterminés lorsque le IF est analysé. Vous pouvez utiliser %~1 et %~2 à l'intérieur du bloc IF, mais ce serait déroutant parce que vous aviez un SHIFT. Vous pouvez mettre le SHIFT à la fin du bloc pour plus de clarté, mais cela pourrait se perdre et / ou confondre les gens ainsi. Donc, "capturer" %~1 et %~1 en dehors du bloc semble le meilleur.
  • Vous ne voulez pas utiliser un paramètre à la place de la valeur optionnelle d'un autre paramètre, vous devez donc vérifier IF NOT "%ARG:~0,2%" == "--".
  • attention seulement à SHIFT {lorsque vous[41]}utiliser l'un des paramètres.
  • Le code en double SET FOO=%DEFAULT_FOO% est regrettable, mais l'autre solution serait d'ajouter un IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% dehors de la IF NOT "%ARG%" == "" bloc. Cependant, comme cela se trouve toujours dans le bloc IF "%PARAM%" == "--foo", la valeur %FOO% aurait été évalué et défini avant d'entrer dans le bloc, de sorte que vous ne détecterez jamais que les deux le paramètre --fooétait présent et aussi que la valeur %FOO% était manquante.
  • notez que ECHO Missing bar value. 1>&2 envoie le message d'erreur à stderr.
  • Vous voulez une ligne vide dans un fichier batch Windows? Tu dois utiliser ECHO: ou l'une des variantes.
1
répondu Garret Wilson 2018-06-02 02:48:08