Sous Windows, comment accéder aux arguments passés lors de l’exécution d’un fichier de commandes?
Par exemple, supposons que j'ai un programme nommé hello.bat
. Lorsque j'entre hello -a
sur une ligne de commande Windows, comment informer mon programme que -a
a été transmis sous forme d'argument?
Comme d'autres l'ont déjà dit, les paramètres transmis via la ligne de commande sont accessibles dans des fichiers de traitement par lots avec la notation %1
à %9
. Vous pouvez également utiliser deux autres jetons:
%0
est nom de l'exécutable (fichier de traitement par lots) spécifié dans la ligne de commande.%*
est tous les paramètres spécifiés dans la ligne de commande - ceci est très utile si vous souhaitez transférer les paramètres à un autre programme.Il y a aussi beaucoup de techniques importantes à connaître en plus de savoir simplement comment accéder aux paramètres.
Ceci est fait avec des constructions comme IF "%~1"==""
, ce qui est vrai si et seulement si aucun argument n'a été passé. Notez le caractère tilde qui supprime toutes les citations environnantes de la valeur de %1
; sans tilde, vous obtiendrez des résultats inattendus si cette valeur inclut des guillemets, y compris la possibilité d’erreurs de syntaxe.
Si vous devez accéder à plus de 9 arguments, vous devez utiliser la commande SHIFT
. Cette commande décale les valeurs de tous les arguments d'une place, de sorte que %0
prenne la valeur de %1
, %1
prenne la valeur de %2
, etc. %9
prend la valeur du dixième argument (s'il en existe un), qui n'était disponible par aucune variable avant d'appeler SHIFT
(entrez la commande SHIFT /?
pour plus d'options).
SHIFT
est également utile lorsque vous souhaitez traiter facilement des paramètres sans exiger qu'ils soient présentés dans un ordre spécifique. Par exemple, un script peut reconnaître les indicateurs -a
et -b
dans n'importe quel ordre. Un bon moyen d’analyser la ligne de commande dans ce cas est
:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!
Ce schéma vous permet d'analyser des lignes de commande assez complexes sans devenir fou.
Pour les paramètres représentant les noms de fichier, le shell offre de nombreuses fonctionnalités liées à l'utilisation de fichiers inaccessibles. On accède à cette fonctionnalité avec des constructions commençant par %~
.
Par exemple, pour obtenir la taille du fichier passé en argument, utilisez
ECHO %~z1
Pour obtenir le chemin du répertoire à partir duquel le fichier de commandes a été lancé (très utile!), Vous pouvez utiliser
ECHO %~dp0
Vous pouvez afficher la gamme complète de ces fonctionnalités en tapant CALL /?
dans l'invite de commande.
Utilisation de paramètres dans les fichiers de commandes:% 0 et% 9
Les fichiers batch peuvent faire référence aux mots passés en tant que paramètres avec les jetons: %0
à %9
.
%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.
les paramètres transmis sur la ligne de commande doivent être des caractères alphanumériques et délimités par des espaces. Puisque %0
est le nom du programme tel qu’il a été appelé, sous DOS %0
sera vide pour AUTOEXEC.BAT s’il est lancé au moment du démarrage.
Exemple:
Placez la commande suivante dans un fichier de commandes appelé mybatch.bat
:
@echo off
@echo hello %1 %2
pause
L'appel du fichier de commandes comme ceci: mybatch john billy
devrait générer:
hello john billy
Obtenez plus de 9 paramètres pour un fichier batch, utilisez:% *
Le jeton de pourcentage d'étoile %*
signifie "le reste des paramètres". Vous pouvez utiliser une boucle for pour les récupérer, comme défini ici:
http://www.robvanderwoude.com/parameters.php
Remarques sur les délimiteurs pour les paramètres de lot
Certains caractères des paramètres de ligne de commande sont ignorés par les fichiers de commandes, selon la version du DOS, qu'ils soient "échappés" ou non, et souvent en fonction de leur emplacement dans la ligne de commande:
commas (",") are replaced by spaces, unless they are part of a string in
double quotes
semicolons (";") are replaced by spaces, unless they are part of a string in
double quotes
"=" characters are sometimes replaced by spaces, not if they are part of a
string in double quotes
the first forward slash ("/") is replaced by a space only if it immediately
follows the command, without a leading space
multiple spaces are replaced by a single space, unless they are part of a
string in double quotes
tabs are replaced by a single space
leading spaces before the first command line argument are ignored
Les fichiers de commandes transmettent automatiquement le texte après le programme, dans la mesure où il s'agit de variables à affecter. Ils sont passés dans l'ordre où ils sont envoyés; par exemple. % 1 sera la première chaîne envoyée après l'appel du programme, etc.
Si vous avez Hello.bat et que le contenu est le suivant:
@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause
et vous appelez le lot en commande via
hello.bat APerson241% date%
vous devriez recevoir ce message:
Bonjour, APerson241 merci d’avoir exécuté ce fichier de commandes (01/11/2013)
Utilisez des variables, à savoir les variables .BAT
et appelées %0
à %9
@ Le système de :parse
/:endparse
de Jon est un bon début. Il a toute ma gratitude pour le premier passage, mais si vous pensez que le système de traitement par lots tortueux de Windows vous permettrait de partir aussi facilement… eh bien, mon ami , vous êtes sous le choc. J'ai passé toute la journée avec ce diable et, après de nombreuses recherches et expériences douloureuses, j'ai finalement réussi à gérer quelque chose de viable pour un utilitaire réel.
Disons que nous voulons implémenter un utilitaire foobar
. Cela nécessite une commande initiale. Il a un paramètre facultatif --foo
qui prend une valeur facultative (qui ne peut évidemment pas être un autre paramètre); Si la valeur est manquante, la valeur par défaut est default
. Il possède également un paramètre facultatif --bar
qui prend une valeur requise . Enfin, vous pouvez utiliser un indicateur --baz
sans valeur. Oh, et ces paramètres peuvent entrer dans n'importe quel ordre.
En d'autres termes, cela ressemble à ceci:
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
Compliqué? Non, cela semble assez typique des services publics réels. (git
quelqu'un?)
Sans plus tarder, 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
Oui, c'est vraiment si mauvais. Voir mon article similaire sur https://stackoverflow.com/a/50653047/421049 , où je fournis une analyse plus détaillée de ce qui se passe dans la logique et de la raison pour laquelle j'ai utilisé certaines constructions.
Hideux. La plupart de cela, j'ai dû apprendre aujourd'hui. Et ça fait mal.