J'ai besoin de transmettre un ID et un mot de passe à un fichier de commandes 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
J'ai besoin de transmettre un ID et un mot de passe à un fichier de commandes 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
Réponses:
Une autre astuce utile consiste à utiliser %*
pour signifier «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 de commandes ci-dessus s'exécutera:
fake-command /u admin /p password admin password foo bar
J'ai peut-être la syntaxe légèrement erronée, mais c'est l'idée générale.
shift
"pop" l'argument de la liste. L'hypothèse d'OP était que %*
cela ne produirait que les arguments restants, mais cela ne fonctionne pas de cette façon, comme l'a dit @Joey.
fake-command /u admin /p password admin password foo bar
. Cela a été souligné par @Joey il y a de nombreuses années.
Voici comment je l'ai fait:
@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 au second. Vous pouvez avoir jusqu'à 9 paramètres transmis de cette façon.
echo %1 %2
et était découragé par le cas le plus simple non coupable et collable avec un @
et un fake-command
avec des paramètres, pensant que nous obtiendrions fake-command.bat
le contenu de plus tard (dans ce cas, le trop compliqué fake-command.bat
peut echo %2 %4
ignorer les noms des paramètres). Faux, doofus. TL; DR: Ne sois pas aussi bête que moi. 1. echo echo %1 %2 > test.bat
2 test word1 word2
.. 3. Bénéfice.
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 de lot peut être simple avec% 1,% 2, ...% 9 ou également% *,
mais uniquement 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 produire d'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, car l'un des &
est en dehors des guillemets.
Il peut être résolu en lisant dans 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 echo on
et à développer% 1 après une rem
instruction (fonctionne également avec %2 .. %*
).
Ainsi, même "&"&
pourrait être répercuté sans produire d'erreur, comme on le fait remarquer.
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 à l'abri de contenus comme /?
(montrerait l'aide pour REM
).
Ou un signe d'insertion ^ à la fin de la ligne peut fonctionner comme un caractère multiligne, même après a rem
.
Ensuite, lisez la sortie du paramètre rem à partir du fichier, mais attentivement.
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 param1
, vous l'avez compris.
Et pour une utilisation param1
sûre, activez l'expansion retardée.
&
, votre solution ne fonctionne qu'avec un contenu simple
test.bat ^&
et il échoue. Fonctionne seulement test.bat "&"
, mais ce n'était pas mon point. Vous ne pouvez pas utiliser %*
, %1
en toute sécurité sans la technique REM
&
et des citations"
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 remplacerez des arguments de ligne de commande (éventuellement nuls) et vous recevrez des messages d'erreur assez déroutants.
if
et for
?
for %%d in (*) do echo %%d
depuis la ligne de commande:for %d in (*) do echo %d
@for %%2 in (testing) do @echo %%2 %1
dans un fichier batch, produit testing 1
quand il est appelé avec 1 ( test 1
).
%%1
n'accède pas à un argument de ligne de commande, et il est également incorrect pour la IF
commande. Seule la FOR
commande (dans les fichiers batch) nécessite des pourcentages doubles, mais même alors %%1
définirait un paramètre FOR et
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 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 batch prend en charge tous les paramètres nécessaires, comme la copie de fichiers uniquement, qui sont plus récents, etc. Je l'ai utilisé depuis avant Windows. Si vous aimez voir les noms des fichiers, tels qu'ils sont copiés, omettez le Q
paramètre.
Un ami m'a posé des questions sur ce sujet récemment, alors j'ai pensé publier comment je gère les arguments de ligne de commande dans des 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 à implémenter. En plus de soutenir les structures suivantes:
>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]
Le jist de celui - ci est d' avoir les :init
, :parse
et les :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"
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
@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue
Remarque: IF "%1"==""
causera des problèmes s'il %1
est placé entre guillemets.
Dans ce cas, utilisez plutôt , IF [%1]==[]
ou dans NT 4 (SP6) et versions ultérieures uniquement IF "%~1"==""
.
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 fait une boucle sur les paramètres du lot (% *), qu'ils soient cités ou non, puis fait écho à chaque paramètre.
test.bat *.txt
, test.bat cat^&dog
ouTest.bat /?
J'ai écrit un simple script read_params qui peut être appelé en tant que fonction (ou externe .bat
) et qui mettra toutes les variables dans l'environnement actuel. Il ne modifiera pas les paramètres d'origine car la fonction est en cours d' call
édition avec 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 en mesure 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
-force
. Vous pouvez utiliser, -force=true
mais je ne peux pas penser à un moyen d'autoriser des valeurs vides sans connaître à l'avance une liste de paramètres qui n'auront pas de valeur.Changelog
-
paramètres avant.Dans un fichier batch
set argument1=%1
set argument2=%2
echo %argument1%
echo %argument2%
% 1 et% 2 renvoient respectivement les première et deuxième valeurs d'argument.
Et en ligne de commande, passez l'argument
Directory> batchFileName admin P@55w0rd
La sortie sera
admin
P@55w0rd
Inspiré par une réponse ailleurs de @ 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
. Il nécessite une commande initiale. Il a un paramètre facultatif --foo
qui prend une valeur facultative (qui ne peut pas être un autre paramètre, bien sûr); si la valeur est manquante, elle est par défaut default
. Il a également un paramètre facultatif --bar
qui prend une 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
SETLOCAL
pour que les variables ne s'échappent pas dans l'environnement appelant.SET FOO=
, etc. au cas où quelqu'un les aurait définies dans l'environnement appelant.%~1
pour supprimer les guillemets.IF "%ARG%" == ""
et non IF [%ARG%] == []
parce que [
et ]
ne jouez pas du tout avec des valeurs se terminant par un espace.SHIFT
dans un IF
bloc, les arguments actuels tels que %~1
ne sont pas mis à jour car ils sont déterminés lorsque l' IF
analyseur est analysé. Vous pouvez utiliser %~1
et %~2
à l'intérieur du IF
bloc, mais ce serait déroutant car vous en avez un SHIFT
. Vous pouvez mettre le SHIFT
à la fin du bloc pour plus de clarté, mais cela pourrait également se perdre et / ou confondre les gens. Donc, "capturer" %~1
et en %~1
dehors du bloc semble le mieux.IF NOT "%ARG:~0,2%" == "--"
.SHIFT
lorsque vous utilisez l' un des paramètres.SET FOO=%DEFAULT_FOO%
est regrettable, mais l'alternative serait d'ajouter un IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%
extérieur au IF NOT "%ARG%" == ""
bloc. Cependant parce que cela est encore à l' intérieur du IF "%PARAM%" == "--foo"
bloc, la %FOO%
valeur aurait été évalué et mis en avant jamais entré dans le bloc, donc vous ne détectez que tant le --foo
paramètre était présent et aussi que la %FOO%
valeur était manquante.ECHO Missing bar value. 1>&2
envoie le message d'erreur à stderr.ECHO:
ou l'une des variantes.Créez un nouveau fichier batch (exemple: openclass.bat) et écrivez cette ligne dans le fichier:
java %~n1
Ensuite, placez 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...
start /wait java %~n1
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
production
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 la commande param dans variable et utilisez variable pour comparaison.
Ce n'est pas seulement simple à écrire mais 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 les autres réponses.
Pour utiliser le bouclage, obtenez tous les arguments et en batch pur:
Obs: Pour une utilisation sans:?*&<>
@echo off && setlocal EnableDelayedExpansion
for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && (
call set "_arg_[!_cnt!]=!_arg_!" && 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 dont il a besoin, comme ...
@echo off && setlocal EnableDelayedExpansion
for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!"
)
fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt
?*&<>