web-dev-qa-db-fra.com

Comment vérifier le paramètre de ligne de commande dans le fichier ".bat"?

Mon système d'exploitation est Windows Vista. J'ai besoin d'un fichier ".bat" dans lequel je dois vérifier si l'utilisateur entre un paramètre de ligne de commande ou non. Si ne puis alors si le paramètre est égal à -b alors je ferai quelque chose sinon je signalerai "Entrée invalide". Si l'utilisateur n'entre aucun paramètre de ligne de commande, je ferai quelque chose. J'ai créé le fichier .bat suivant. Cela fonctionne pour -b et non égal à -b cas - mais cela échoue lorsque l'utilisateur ne passe aucun paramètre de ligne de commande.

J'ai toujours des erreurs:

GOTO was unexpected at this time.

Quelqu'un peut-il me dire ce que je fais mal ici?


ECHO OFF
CLS
ECHO.

IF [%1]==[/?] GOTO BLANK

IF %1=="-b" GOTO SPECIFIC

IF NOT %1=="-b" GOTO UNKNOWN

:SPECIFIC

ECHO SPECIFIC

GOTO DONE

:BLANK

ECHO No Parameter

GOTO DONE

:UNKNOWN

ECHO Unknown Option

GOTO DONE

:DONE

ECHO Done!
91
javauser71

Vous devez vérifier si le paramètre est vide: if "%~1"=="" goto blank

Une fois que vous avez fait cela, alors faites un if/else sur -b: if "%~1"=="-b" (goto specific) else goto unknown

Entourer les paramètres de guillemets facilite la vérification d'éléments tels que les paramètres vides/vides/manquants. "~" garantit que les guillemets doubles sont supprimés s'ils figuraient sur l'argument de la ligne de commande.

129
afrazier

Regardez http://ss64.com/nt/if.html pour obtenir une réponse. la commande est IF [%1]==[] GOTO NO_ARGUMENT ou similaire.

26
Jeremiah Willcock

La réponse courte - utilisez des crochets:

if [%1]==[] goto :blank

ou (lorsque vous aurez besoin de gérer des arguments cités, voir Edit ci-dessous):

if [%~1]==[] goto :blank

Pourquoi? vous pourriez demander. Comme Jeremiah Willcock l'a mentionné: http://ss64.com/nt/if.html - ils l'utilisent! OK, mais quel est le problème avec les citations?

Encore une fois, réponse courte: ils sont "magiques" - parfois les doubles (doubles) guillemets sont convertis en une seule (double) guillemets. Et ils doivent correspondre, pour commencer.

Considérez ce petit script:

@rem argq.bat
@echo off

:loop 
if "%1"=="" goto :done
echo %1
shift
goto :loop

:done
echo Done.

Testons le:

C:\> argq bla bla
bla
bla
Done.

Semble travailler. Mais maintenant, passons en deuxième vitesse:

C:\> argq "bla bla"
bla""=="" was unexpected at this time.

Boom Cela n'a pas été évalué comme étant vrai, ni comme faux. Le script est mort. Si vous étiez censé éteindre le réacteur quelque part sur la ligne, alors bonne chance. Vous allez maintenant mourir comme Harry Daghlian.

Vous pensez peut-être - OK, les arguments ne peuvent pas contenir de guillemets. Si c'est le cas, cela se produit. Wrong Voici une consolation:

C:\> argq ""bla bla""
""bla
bla""
Done.

Oh oui. Ne vous inquiétez pas - parfois cela sera fonctionne.

Essayons un autre script:

@rem args.bat
@echo off

:loop 
if [%1]==[] goto :done
echo %1
shift
goto :loop

:done
echo Done.

Vous pouvez tester vous-même que cela fonctionne bien pour les cas ci-dessus. C'est logique - les guillemets n'ont rien à voir avec des crochets, il n'y a donc pas de magie ici. Mais qu'en est-il de pimenter les arguments avec des crochets?

D:\>args ]bla bla[
]bla
bla[
Done.

D:\>args [bla bla]
[bla
bla]
Done.

Pas de chance là-bas. Les crochets ne peuvent tout simplement pas étouffer l'analyseur de cmd.exe.

Revenons un instant aux citations perverses. Le problème était là, quand l'argument s'est terminé par une citation:

D:\>argq "bla1 bla2"
bla2""=="" was unexpected at this time.

Et si je passe juste:

D:\>argq bla2"
The syntax of the command is incorrect.

Le script ne fonctionnera pas du tout. Idem pour args.bat:

D:\>args bla2"
The syntax of the command is incorrect.

Mais que puis-je obtenir lorsque le nombre de " - caractères "correspond" (c'est-à-dire - est pair), dans un tel cas:

D:\>args bla2" "bla3
bla2" "bla3
Done.

Nice - J'espère que vous avez appris quelque chose sur la façon dont les fichiers .bat Divisent leurs arguments en ligne de commande (CONSEIL: * Ce n'est pas exactement comme dans bash) . L'argument ci-dessus contient un espace. Mais les citations ne sont pas automatiquement supprimées.

Et argq? Comment réagit-il à cela? De manière prévisible:

D:\>argq bla2" "bla3
"bla3"=="" was unexpected at this time.

Alors, réfléchissez avant de dire: "Vous savez quoi? Utilisez simplement des guillemets. [Parce que, pour moi, cela a l'air plus joli]".

Modifier

Récemment, il y a eu des commentaires à propos de cette réponse - bon, les crochets carrés "ne peuvent pas gérer" en passant les arguments cités et en les traitant comme s'ils n'étaient pas cités.

La syntaxe:

if "%~1"=="" (...)

Il ne s’agit pas d’une vertu nouvellement trouvée des guillemets doubles, mais de l’affichage d’une fonction intéressante de suppression des guillemets de la variable argument, si les premier et dernier caractères sont des guillemets doubles.

Cette "technologie" fonctionne aussi bien avec les crochets:

if [%~1]==[] (...)

C'était une chose utile de souligner cela, donc j'avance également la nouvelle réponse.

Enfin, citation double, un argument de la forme "" Existe-t-il dans votre livre ou est-il vide? Je demandais juste' ;)

14
Tomasz Gandor

En plus des autres réponses, auxquelles je suis abonné, vous pouvez envisager d’utiliser le /I _ commutateur de la commande IF.

... le commutateur/I, s'il est spécifié, indique que la comparaison des chaînes sans distinction de casse.

cela peut être utile si vous souhaitez donner à vos utilisateurs une flexibilité qui leur permet de spécifier les paramètres.

IF /I "%1"=="-b" GOTO SPECIFIC
8
PA.

En fait, toutes les autres réponses ont des défauts. Le moyen le plus fiable est:

IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

Explication détaillée:

En utilisant "%1"=="-b" va écraser complètement si on passe des arguments avec des espaces et des guillemets C'est la méthode la moins fiable.

IF "%1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat "a b"

b""=="-b" was unexpected at this time.

En utilisant [%1]==[-b] est préférable car il ne plantera pas d'espaces ni de guillemets, mais il ne correspondra pas si l'argument est entouré de guillemets.

IF [%1]==[-b] (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat "-b"

(does not match, and jumps to UNKNOWN instead of SPECIFIC)

En utilisant "%~1"=="-b" est le plus fiable. %~1 enlèvera les guillemets s'ils existent. Donc, cela fonctionne avec et sans guillemets, et aussi sans argument.

IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat
C:\> run.bat -b
C:\> run.bat "-b"
C:\> run.bat "a b"

(all of the above tests work correctly)
5
wisbucky

Vous comparez des chaînes. Si des arguments sont omis, %1 devient vide et les commandes deviennent IF =="-b" GOTO SPECIFIC _ par exemple (qui est une erreur de syntaxe). Enveloppez vos chaînes entre guillemets (ou entre crochets).

REM this is ok
IF [%1]==[/?] GOTO BLANK

REM I'd recommend using quotes exclusively
IF "%1"=="-b" GOTO SPECIFIC

IF NOT "%1"=="-b" GOTO UNKNOWN
5
Jeff Mercado