Question

Je dois transmettre un identifiant et un mot de passe à un fichier de commandes au moment de son 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
Était-ce utile?

La solution 2

Voici comment j'ai procédé :

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

Voici à quoi ressemble la 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 à la seconde.Vous pouvez transmettre jusqu'à 9 paramètres de cette manière.

Autres conseils

Un autre conseil 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% %*

Quand vous courez :

test-command admin password foo bar

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

fake-command /u admin /p password admin password foo bar

J'ai peut-être une syntaxe légèrement erronée, mais c'est l'idée générale.

Si vous souhaitez 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

L'accès aux paramètres du lot peut être simple avec %1, %2, ...%9 ou encore %*,
mais seulement si le contenu est simple.

Il n'existe pas de moyen simple pour des contenus complexes comme "&"^&, car il n'est pas possible d'accéder à %1 sans produire une erreur.

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

Les lignes s'étendent jusqu'à

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

Et chaque ligne échoue, comme l'un des & est en dehors des guillemets.

Cela peut être résolu en lisant à partir d'un fichier temporaire un remarqué version 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éveloppez le %1 après un rem déclaration (fonctionne également avec %2 .. %*).
Alors 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 personnages supplémentaires * # sont utilisés pour être en sécurité contre des contenus comme /? (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.

Puis en lisant le paramètre rem sortie du fichier, mais avec précaution.
Le For / F devrait fonctionner avec une expansion retardée, sinon le contenu de "!" serait détruit.
Après avoir supprimé les caractères supplémentaires dans param1, tu l'as eu.

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

Oui, et n'oubliez pas d'utiliser des variables comme %%1 lors de l'utilisation if et for et la bande.

Si tu oublies le double %, vous remplacerez alors les arguments de ligne de commande (éventuellement nuls) et vous recevrez des messages d'erreur assez déroutants.

Il n’est pas nécessaire de compliquer les choses.Il s'agit simplement de 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 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 batch prend en charge tous les paramètres nécessaires, comme la copie uniquement des fichiers, les plus récents, etc.Je l'utilise depuis avant Windows.Si vous aimez voir les noms des fichiers au fur et à mesure de leur copie, laissez de côté le Q paramètre.

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

Note:SI "%1"=="" causera des problèmes si %1 est lui-même entouré de guillemets.

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

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

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

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

L'essentiel, c'est d'avoir le :init, :parse, et :main les 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.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 depuis 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 paramètres du lot (%*), qu'ils soient cités ou non, puis fait écho à chaque paramètre.

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

Par exemple, étant donné 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 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 tels que -force.Vous pourriez utiliser -force=true mais je ne vois pas de moyen d'autoriser des valeurs vides sans connaître à l'avance une liste de paramètres qui n'auront pas de valeur.

Journal des modifications

  • 2/18/2016
    • Ne nécessite plus d'expansion retardée
    • Fonctionne désormais avec d'autres arguments de ligne de commande en recherchant - avant les paramètres.

Pour faire référence à une variable définie en ligne de commande, vous devrez utiliser %a% donc par exemple :

set a=100 
echo %a%  
rem output = 100 

Note:Cela fonctionne pour Windows 7 professionnel.

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

java %~n1

Placez ensuite le fichier batch dans, 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 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...

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

Disons que nous voulons implémenter un utilitaire foobar.Cela nécessite une commande initiale.Il a un paramètre facultatif --foo ce qui prend un facultatif valeur (qui ne peut pas être un autre paramètre, bien sûr) ;si la valeur est manquante, la valeur par défaut est default.Il possède également un paramètre facultatif --bar ce qui prend un requis valeur.Enfin, il peut prendre un drapeau --baz sans aucune 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
  • Utiliser SETLOCAL afin 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.
  • Utiliser %~1 pour supprimer les guillemets.
  • Utiliser IF "%ARG%" == "" et pas IF [%ARG%] == [] parce que [ et ] ne jouez pas du tout à will avec des valeurs se terminant par un espace.
  • Même si vous SHIFT à l'intérieur d'un IF bloc, les arguments actuels tels que %~1 ne sont pas mis à jour car ils sont déterminés lorsque le IF est analysé.Vous pourriez utiliser %~1 et %~2 à l'intérieur de IF bloquer, mais ce serait déroutant car vous aviez un SHIFT.Tu pourrais mettre le SHIFT à la fin du bloc pour plus de clarté, mais cela pourrait également se perdre et/ou dérouter les gens.Donc "capturer" %~1 et %~1 en dehors du pâté de maisons semble le mieux.
  • Vous ne souhaitez 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 seulement à SHIFT lorsque vous utiliser un des paramètres.
  • Le code en double SET FOO=%DEFAULT_FOO% est regrettable, mais l'alternative serait d'ajouter un IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% en dehors de IF NOT "%ARG%" == "" bloc.Cependant, comme c'est toujours à l'intérieur du IF "%PARAM%" == "--foo" bloquer, le %FOO% la valeur aurait été évaluée et définie avant que vous n'entriez dans le bloc, vous ne le détecteriez donc jamais les deux le --foo le paramètre était présent et aussi que le %FOO% la valeur manquait.
  • Noter 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.

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

AppelTest1.bat

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

sortir

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

Pour garder les choses simples, stockez le paramètre de commande dans une variable et utilisez la variable à des fins de 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, il sera facile à comprendre et à maintenir.

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

enter image description here

Pour utiliser le bouclage, récupérez tous les arguments et en pur batch :

@echo off && setlocal EnableDelayedExpansion

 set "_cnt=0" && for %%Z in (%*) do ( 
 set "_arg_=%%Z" && set /a "_cnt=!_cnt! + 1" && set "_arg_[!_cnt!]=!_arg_!"
 shift && for /l %%l in (!_cnt! 1 !_cnt!) do echo/ The argument n:%%l is: !_arg_[%%l]!
 )

goto :eof 

Votre code est prêt à faire quelque chose avec le numéro d'argument là où il en a besoin, comme...

 @echo off && setlocal EnableDelayedExpansion

 set "_cnt=0" && for %%Z in (%*) do ( 
 set "_arg_=%%Z" && set /a "_cnt=!_cnt! + 1" && set "_arg_[!_cnt!]=!_arg_!"
 shift 

 )

 fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top