J'ai besoin de mon fichier bat pour accepter plusieurs arguments nommés facultatifs.
mycmd.bat man1 man2 -username alice -otheroption
Par exemple, ma commande a 2 paramètres obligatoires et deux paramètres optionnels (-username) qui ont une valeur d'argument alice et -otheroption:
J'aimerais être en mesure de regrouper ces valeurs en variables.
Il suffit d'appeler quiconque a déjà résolu ce problème. Mec, ces fichiers de chauve-souris sont une douleur.
batch-file
poulet au poulet
la source
la source
http://web.archive.org/web/20090403050231/http://www.pcguide.com/vb/showthread.php?t=52323
.Réponses:
Bien que j'ai tendance à être d'accord avec le commentaire de @AlekDavis , il existe néanmoins plusieurs façons de le faire dans le shell NT.
L'approche je tirerais parti de la commande SHIFT et du branchement conditionnel IF , quelque chose comme ça ...
la source
SHIFT /2
décalages commençant à arg 2. Il ne se décale pas deux fois. Ne devrait-il pas être remplacé parSHIFT & SHIFT
?mycmd.bat -username anyvalue -username myName -otheroption othervalue
. Le résultat doit être user = myName, other = othervalue; mais le code donne user = -username, other = othervalue. Le bogue est corrigé en remplaçantSHIFT /2
parSHIFT & SHIFT
.;
- il ne peut pas être utilisé à la place de&
.%1
et%2
ont été «Utilisé». b) Le simpleSHIFT
de la ligne 11 déplace la valeur de%2
1 position vers le bas et est alors disponible (à nouveau) comme%1
, et la valeur "Inutilisé" de%3
est disponible comme%2
. c) LaIF
ligne 13 voit cette valeur déjà "Utilisée" à partir de%2
laquelle se trouve maintenant%1
. d) Si le "nom d'utilisateur" de la ligne 10 ressemble à celui"-otheroption"
-ci, il sera utilisé à nouveau etother
sera mis à la nouvelle valeur dans%2
, qui était probablement le nom de l'option suivante. --->-otheroption
n'était pas suivi d'une valeur, il était donc probablement conçu comme une-Flag
option de type et ne devrait pas consommer un deuxième argument. 3ème: Si l'argument%1
n'est pas traité par l'interneIF
instructions , il est ignoré en silence. Le code devrait probablement afficher un message indiquant qu'il ne s'agissait pas d'une option valide. Cela pourrait être fait en ajoutant les instructions requisesSHIFT
etGOTO :loop
dans lesIF
instructions internes , ou en ajoutant uneELSE
instruction.La réponse choisie fonctionne, mais elle pourrait nécessiter une certaine amélioration.
Ma solution repose sur la création d'une variable OPTIONS qui définit toutes les options et leurs valeurs par défaut. OPTIONS est également utilisé pour tester si une option fournie est valide. Une énorme quantité de code est enregistrée en stockant simplement les valeurs d'option dans des variables nommées de la même manière que l'option. La quantité de code est constante quel que soit le nombre d'options définies; seule la définition OPTIONS doit changer.
EDIT - De plus, le code de la boucle: doit changer si le nombre d'arguments de position obligatoires change. Par exemple, souvent, tous les arguments sont nommés, auquel cas vous voulez analyser les arguments commençant à la position 1 au lieu de 3. Ainsi, dans la boucle:, tous les 3 deviennent 1 et 4 devient 2.
Il n'y a vraiment pas beaucoup de code. La plupart des codes ci-dessus sont des commentaires. Voici exactement le même code, sans les commentaires.
Cette solution fournit des arguments de style Unix dans un lot Windows. Ce n'est pas la norme pour Windows - batch a généralement les options précédant les arguments requis et les options sont préfixées avec
/
.Les techniques utilisées dans cette solution sont facilement adaptées à un style d'options Windows.
%1
, et continue jusqu'à ce que arg 1 ne commence pas par/
/
.SET /VAR=VALUE
échoueSET "/VAR=VALUE"
fonctionne. Je fais déjà cela dans ma solution de toute façon./
. Cette limitation peut être éliminée en employant une//
option implicitement définie qui sert de signal pour quitter la boucle d'analyse des options. Rien ne serait stocké pour//
"l'option".Mise à jour 28/12/2015: Prise en charge de
!
en valeurs d'optionDans le code ci-dessus, chaque argument est développé tandis que l'expansion retardée est activée, ce qui signifie qu'il
!
est probablement supprimé, ou bien quelque chose comme!var!
est développé. En outre,^
peut également être dépouillé s'il!
est présent. La petite modification suivante du code non commenté supprime la limitation telle que!
et^
sont conservés dans les valeurs d'option.la source
Si vous souhaitez utiliser des arguments facultatifs, mais pas des arguments nommés, cette approche a fonctionné pour moi. Je pense que c'est un code beaucoup plus facile à suivre.
la source
IF "%1"==""
échouera si l'argument contient lui-même des guillemets. Utilisez simplement un autre symbole non spécial à la place, comme ._ = [] # etcCréation de variables dynamiques
Avantages
%1
,%2
...%*
dans le tact/arg
et le-arg
styleLes inconvénients
setlocal
pour la portée locale ou écrivez une:CLEAR-ARGS
routine d' accompagnement !--force
pour-f
)""
support d'argument videUsage
Voici un exemple de relation entre les arguments suivants et les variables .bat:
la mise en oeuvre
la source
:ARG-PARSER
routine vers un fichier .bat externe commearg-parser.bat
pour le rendre également disponible pour d'autres scripts.Une fois que j'ai écrit un programme qui gère les arguments courts (-h), longs (--help) et non-option dans le fichier de commandes. Ces techniques comprennent:
arguments non-option suivis par des arguments d'options.
opérateur shift pour les options qui n'ont pas d'argument comme '--help'.
deux opérateurs de décalage temporel pour les options qui nécessitent un argument.
boucle à travers une étiquette pour traiter tous les arguments de ligne de commande.
Quittez le script et arrêtez le traitement pour les options qui ne nécessitent aucune action supplémentaire comme «--help».
Rédaction de fonctions d'aide pour guider l'utilisateur
Voici mon code.
la source
Voici l'analyseur d'arguments. Vous pouvez mélanger tous les arguments de chaîne (conservés intacts) ou les options échappées (simples ou paires option / valeur). Pour le tester, décommentez les 2 dernières instructions et exécutez-le comme:
Le caractère d'échappement est défini comme
"_SEP_=/"
, redéfinir si nécessaire.la source