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?


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 

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.


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.


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"

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

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 .


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
)

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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.