Comment puis-je vérifier si un argument est défini lors du démarrage / de l'appel d'un fichier batch?

96

J'essaie d'utiliser la logique de validation suivante dans un fichier de commandes, mais le bloc "utilisation" ne s'exécute jamais même si aucun paramètre n'est fourni au fichier de commandes.

if ("%1"=="") goto usage

@echo This should not execute

@echo Done.
goto :eof

:usage
@echo Usage: %0 <EnvironmentName>
exit 1

Qu'est-ce que je fais mal?

Daniel Fortunov
la source

Réponses:

146

La vérification pour savoir si un argument de ligne de commande a été défini peut être [%1]==[], mais, comme le souligne Dave Costa , fonctionnera également."%1"==""

J'ai également corrigé une erreur de syntaxe dans l'écho d'utilisation pour échapper aux signes supérieur à et inférieur à. De plus, les exitbesoins d'un /Bargument se CMD.exetermineront autrement .

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1
Iain
la source
18
[% 1] == [] est meilleur que "% 1" == "" car il gérera correctement le cas où% 1 lui-même contient des guillemets doubles. "% 1" == "" affichera une erreur avec un message "inattendu pour le moment".
tekumara
2
Notez que, si vous n'utilisez pas d'arguments de ligne de commande mais des setvariables (je ne connais pas la terminologie correcte des lots), vous voudrez peut-être utiliser "%myvar%"==""car s'il myvarcontient des espaces et n'est pas entre guillemets, vous obtiendrez le "inattendu pour le moment " message.
Pat
1
Les variables @Pat SET peuvent être vérifiées avec IF NOT DEFINED VarNameblock. Également +1 à tukushan pour ne pas utiliser de guillemets en comparaison. Ne fais pas ça. Jamais.
Ven
10
"%~1"==""fonctionnera également et s'occupera du cas où% 1 a des guillemets doubles
Drakkim
8
"%~1"==""gère les espaces dans la variable alors que la []version ne le fait pas.
Cookie Butter le
17

Un exemple plus avancé:

⍟ arguments illimités.

⍟ existe sur un système de fichiers (soit fileou directory?) Ou un générique string.

⍟ spécifier si est un fichier

⍟ spécifier est un répertoire

pas d' extensions, fonctionnerait dans les scripts hérités!

code minimal ☺

@Écho off

:boucle
      :: -------------------------- a un argument?
      si ["% ~ 1"] == [""] (
        écho fait.
        aller à la fin
      )
      :: -------------------------- argument existe?
      s'il n'existe pas% ~ s1 (
        l'écho n'existe pas
      ) autre (
        l'écho existe
        s'il existe% ~ s1 \ NUL (
          echo est un répertoire
        ) autre (
          echo est un fichier
        )
      )
      :: --------------------------
      décalage
      aller en boucle
      
      
:fin

pause

✨ d'autres trucs..✨

■ in %~1- le ~supprime tout emballage "ou '.

■ in %~s1- the scrée le chemin DOS 8.3 naming, ce qui est une bonne astuce pour éviter les espaces dans le nom du fichier lors de la vérification des éléments (et de cette façon, il n'est pas nécessaire d'envelopper la ressource avec plus de "s.

■ le ["%~1"]==[""]"ne peut pas être sûr" si l'argument est un fichier / répertoire ou juste une chaîne générique encore, donc à la place l'expression utilise des crochets et l'original non modifié %1(juste sans le "wrapping, le cas échéant ..)

s'il n'y avait aucun argument de si nous avons utilisé shiftet que le pointeur arg-list a passé le dernier, l'expression sera évaluée [""]==[""].

■ c'est aussi spécifique que vous pouvez l'être sans utiliser plus d'astuces (cela fonctionnerait même dans les scripts batch de Windows-95 ...)

■ exemples d'exécution

enregistrez-le sous identifier.cmd

il peut identifier un nombre illimité d'arguments (normalement vous êtes limité à %1- %9), rappelez-vous simplement de placer les arguments avec des virgules inversées, ou d'utiliser un nom 8.3, ou de les glisser-déposer (il fait automatiquement l'une des deux ci-dessus).


cela vous permet d'exécuter les commandes suivantes:

identifier.cmd c:\windows et pour obtenir

exister
est un directeur
terminé

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" et pour obtenir

exister
est un fichier
terminé

⓷ et de multiples arguments (bien sûr, c'est l'affaire complète ..)

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

et pour obtenir

exister
est un directeur
exister
est un fichier
exister
est un fichier
n'existe pas
terminé.

naturellement, cela peut être beaucoup plus complexe, mais les bons exemples doivent toujours être simples et minimaux. :)

J'espère que cela aide n'importe qui :)

publié ici: CMD Ninja - Traitement illimité des arguments, identifiant s'il existe dans le système de fichiers, identifiant si un fichier ou un répertoire

et voici un exemple de travail qui prend n'importe quelle quantité de fichiers APK (applications Android) et les installe sur votre appareil via la console de débogage (ADB.exe): Faites de l'article précédent un programme d'installation APK de masse qui n'utilise pas la syntaxe ADB Install-Multi

Communauté
la source
14

Débarrassez-vous des parenthèses.

Exemple de fichier batch:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

Sortie de l'exécution du script ci-dessus:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

Je pense qu'il faut en fait prendre les parenthèses pour faire partie des chaînes et elles sont comparées.

Dave Costa
la source
1
if "%1"==""plantera si l'argument a des espaces. Par exemple: run.bat "a b". @amr a la meilleure réponse à utiliserif "%~1"==""
wisbucky
6
IF "%~1"=="" GOTO :Usage

~ supprimera% 1 si% 1 lui-même est cité.

"" protégera des caractères spéciaux passés. par exemple en appelant le script avec & ping

Amr Ali
la source
1
C'est la meilleure réponse. Les autres réponses fonctionnent pour certains cas, mais échoueront pour des cas plus spéciaux commerun.bat "a b"
wisbucky
@wisbucky Cela ne semble pas gâcher la réponse acceptée . Qu'est-ce que je rate?
ruffin
@ruffin, Exemple: run.bat ""ne sera pas attrapé par avec [%1]==[].
wisbucky
2
IF "%1"=="" GOTO :Continue
.....
.....
:Continue
IF "%1"=="" echo No Parameter given
Howard Rothenburg
la source
Cela plante pendantrun.bat "a b"
wisbucky
2

C'est la même chose que les autres réponses, mais n'utilise qu'une seule étiquette et met l'utilisation en premier, ce qui en fait également une sorte de documentation recommandée pour le script qui est également généralement placé en haut:

@echo off
:: add other test for the arguments here...
if not [%1]==[] goto main
:: --------------------------
echo This command does something.
echo.
echo %0 param%%1 param%%2
echo       param%%1 the file to operate on
echo       param%%1 another file

:: --------------------------
exit /B 1

:main
:: --------------------------
echo do something with all arguments (%%* == %*) here...

Cependant, si vous n'avez pas à utiliser cmd / batch, utilisez bash sur WSL ou powershell, ils ont une syntaxe plus saine et moins de fonctionnalités arcanes.

masterxilo
la source
0

SI "% 1" == "" échouera, toutes les versions de ceci échoueront sous certaines conditions de caractère empoisonné. Seuls SI DEFINI ou SI NON DEFINI sont sûrs

codé
la source
if [not] defined ...ne fonctionne pas avec des paramètres comme %1. Avez-vous un exemple, où if "%~1" ...ne fonctionne pas?
Stephan