Déterminer si la commande est reconnue dans un fichier de commandes

43

J'écris un script chauve-souris dans lequel j'appelle un programme (tel que javac). Pour simplifier, je veux vérifier si la commande existe avant de l'exécuter. c'est-à-dire si la commande existe dans PATH.

Par exemple,

if (my_command.exe is a recognized command) then (
  my_command.exe my_args
) else (
  REM Output was probably "'my_command.exe' is not recognized as an internal or external command, operable program or batch file."
  REM Do not run my_command.exe
)

Quelle est la meilleure façon de faire cela dans Windows?

utilisateur46097
la source
Comment allez-vous "reconnaître" votre commande?
Rook
Sous MS-DOS (vrai DOS), c'était assez simple. vous venez de vérifier l'existence d'un fichier exe dans c: \ dos; mais même alors, la question demeure.
Rook
Désolé pour la confusion. Je voulais dire essentiellement une invite de commande dans Windows. Si je tape "lkajsflksajdfj", je veux détecter que ce n'est pas une commande. Si je tape "notepad.exe", c'est bon.
user46097

Réponses:

54
WHERE mycommand
IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 
Josh Santangelo
la source
10
Si quelqu'un ne veut pas que la sortie soit affichée dans la fenêtre de commande, ajoutez-la >nul 2>nulderrière le mycommand.
Sébastien
Notez qu'il y a plus de canaux de sortie que 1 et 2, puisque 1 représente le tampon de sortie et 2 le tampon d'erreur, cela dépend de la façon dont l'application a été développée, cela devrait fonctionner pour les applications courantes livrées avec Windows, mais un programme CLI spécifique pourrait continue de lancer du texte lorsque les canaux 1 et 2 sont redirigés.
ElektroStudios
15

Le code ci-dessous doit toujours s'exécuter proprement, sans sortie de mémoire.

javac -version >nul 2>&1 && (
    echo found javac
) || (
    echo fail
)

Sortie:

found javac

Le même code qu'un one-liner:

javaz -version >nul 2>&1 && ( echo found javac ) || ( echo fail )

Sortie:

fail

Notez que l'ordre &&et ||semble avoir de l'importance. En outre, la commande dont vous testez l'existence doit être renvoyée avec un niveau d'erreur <= 0 pour que cela fonctionne. Espérons que la commande a /? ou --help arguments ou, comme avec java, une commande d'informations de version.

vert
la source
Cette solution est parfaite!
Robe007 Le
7

Le moyen le plus simple consiste simplement à exécuter la commande, mais cela pose bien sûr d'autres problèmes, car vous ne voulez peut-être pas lancer un processus aléatoire.

for %%x in (my_command.exe) do if not [%%~$PATH:x]==[] set MyCommandFound=1

est une alternative qui recherche le programme dans les chemins listés par la %PATH%variable d'environnement. C'est essentiellement une version pure batch de which(1). On peut faire mieux, mais en gros, c'est ça.

Joey
la source
1
C'est parfait, fait exactement ce qui était demandé!
Pez Cuckow
3

Pour ma situation. Le moyen le plus simple consiste à utiliser le || ou && opérateur.

my_command.exe -version 2>NUL && echo "my_command exists"

ou

my_command.exe -version 2>NUL || echo "my_command doesn't exist"
utilisateur46097
la source
Pourquoi ne redirigez-vous pas trop stdout?
Joey
3

Quelques améliorations à la version ci-dessous. Testez cette commande et supprimez les sorties inutiles.

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found
Yuliskov
la source
où <mon_exe> NUL 2> & 1 || echo my.exe n'existe pas && goto: EOF fonctionne bien dans les scripts
Robert
NB: Cela ne fonctionne pas si le nom de fichier que vous voulez tester comprend des informations sur le chemin. Par exemple, WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Jonathan Gilbert
1

Si l'installation d'outils supplémentaires est correcte, une wherecommande est incluse dans les kits de ressources. voir l' équivalent Windows de whereis? .

Sinon, pour les versions de Windows qui ne sont pas trop anciennes, c'est faisable pur cmd, comme indiqué dans la recherche exécutable de Dos sauf PATH .

Gilles, arrête de faire le mal
la source
Merci pour la reponse! Malheureusement, l’une des conditions requises est qu’il doit s’exécuter sur une boîte vanilla (ordinateurs XP inclus).
user46097
2
Le deuxième lien que Gilles a donné a une solution astucieuse qui utilise FOR et aucun outil supplémentaire.
Paradroid
1

Je sais que ce n’est pas tout à fait ce que vous recherchez, mais avec un léger changement de logique, il devrait répondre à vos besoins.

Chaque commande exécutée a un code de retour (ou errorlevel). Si le code de retour est 0 (zéro), la commande a été exécutée avec succès. Si le code de retour est supérieur à 0, quelque chose s'est mal passé.

Voir ici pour plus de détails.

Quelque chose comme -

my_command
if (%ERRORLEVEL% > 0) then (
  REM Output was probably "'my_command.exe' is not recognized as an internal or external command, operable program or batch file.  OR SOMETHING WENT WRONG WITH IT."
  REM Do not run my_command.exe
)
Bryan
la source
C'est malin, je l'aime bien.
Shinrai
Oui, mais c'est moche, car si la commande n'est pas trouvée, une erreur de 2 lignes est renvoyée. Donc, une solution plus propre pourrait éventuellement être trouvée.
djangofan
0

Bien que tous ces moyens puissent fonctionner, pourquoi ne pas les intégrer?

If exists my_command do echo "my_command exists"

Exécuter "si /?" sur la ligne de commande pour plus de détails

uSlackr
la source
5
Cela cherchera seulement si un fichier / répertoire avec ce nom existe dans le répertoire actuel. Cela ne donne aucune indication quant à l'existence d'une commande exécutable portant ce nom, car elle permet de déterminer si vous devez effectuer une recherche dans le fichier PATH.
Joey