Determina se il comando è riconosciuto in un file batch


43

Sto scrivendo una sceneggiatura di pipistrelli in cui invoco un programma (come javac). Per semplicità, voglio verificare se il comando esiste prima di eseguirlo. cioè se il comando esiste in PERCORSO.

Per esempio,

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
)

Qual è il modo migliore per farlo in Windows?


Come "riconoscerai" il tuo comando?
Rook,

In MS-DOS (vero DOS) questo era piuttosto semplice; hai appena verificato l'esistenza di un file exe in c: \ dos; ma anche allora la domanda rimane.
Rook,

Dispiace per la confusione. Intendevo essenzialmente un prompt dei comandi in Windows. Se digito "lkajsflksajdfj" voglio rilevare che non è un comando. Se digito "notepad.exe", va bene.
user46097

Risposte:


54
WHERE mycommand
IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 

10
Se qualcuno non desidera l'output all'interno della finestra cmd, aggiungi semplicemente >nul 2>nuldietro mycommand.
Sebastian,

Si noti che esistono più canali di output rispetto a 1 e 2, poiché 1 sta per buffer di output e 2 per buffer di errore, dipende da come è stata sviluppata l'applicazione, dovrebbe funzionare per le app comuni fornite con Windows, ma un programma CLI specifico potrebbe continua a lanciare testo quando i canali 1 e 2 vengono reindirizzati.
ElektroStudios,

15

Il codice seguente dovrebbe sempre essere eseguito in modo pulito senza output di immondizia.

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

Produzione:

found javac

Lo stesso codice di una riga:

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

Produzione:

fail

Si noti che l'ordine di &&e ||sembra importare. Inoltre, il comando di cui stai verificando l'esistenza deve tornare con un livello di errore <= 0 affinché funzioni. Speriamo che il comando abbia /? oppure --help argomenti o, come con java, un comando info versione.


Questa soluzione è perfetta!
robe007,

7

Il modo più semplice è semplicemente eseguire il comando, ma questo ha altri problemi, ovviamente, dal momento che forse non si desidera avviare un processo casuale.

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

è un'alternativa che cerca il programma nei percorsi elencati dalla %PATH%variabile d'ambiente. È essenzialmente una versione batch pura di which(1). Può essere migliorato ma essenzialmente è così.


1
Questo è perfetto, fa esattamente quello che è stato chiesto!
Pez Cuckow,

3

Per la mia situazione Il modo più semplice assoluto è usare || o operatore &&.

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

o

my_command.exe -version 2>NUL || echo "my_command doesn't exist"

Perché non reindirizzi anche stdout?
Joey,

3

Alcuni perfezionamenti alla versione seguente. Testare quel comando esiste e sopprimere l'output non necessario.

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found

dove <my_exe> NUL 2> & 1 || echo my.exe non esiste && goto: EOF funziona bene negli script
Robert

NB: Questo non funziona se il nome del file che si desidera verificare include le informazioni sul percorso. Ad esempio, WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Jonathan Gilbert,

1

Se richiedere l'installazione di strumenti extra è ok, c'è un wherecomando nei kit di risorse; vedi l' equivalente di Windows di dov'è? .

Altrimenti, per le versioni di Windows che non sono troppo antiche, è fattibile in puro cmd, come menzionato nella ricerca eseguibile Dos tranne PATH .


Grazie per la risposta! Sfortunatamente, uno dei requisiti è che deve essere eseguito su una scatola di vaniglia (macchine XP incluse), quindi dove non è un'opzione.
user46097

2
Il secondo collegamento fornito da Gilles ha una soluzione elegante che utilizza FOR e senza strumenti aggiuntivi.
paradroid,

1

So che non è esattamente quello che stai cercando, ma con un leggero cambiamento nella logica dovrebbe realizzare ciò di cui hai bisogno.

Ogni comando eseguito ha un codice di ritorno (aka errorlevel), se il codice di ritorno è 0 (zero), il comando è stato eseguito correttamente, se il codice di ritorno è maggiore di 0, qualcosa è andato storto.

Vedi qui per maggiori dettagli.

Qualcosa di simile a -

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
)

Questo è intelligente, mi piace.
Shinrai,

Sì, ma è brutto da allora, se il comando non viene trovato genera un errore di 2 righe. Quindi, è possibile trovare una soluzione più pulita.
Djangofan,

0

Mentre tutto ciò potrebbe funzionare, perché non quello integrato?

If exists my_command do echo "my_command exists"

Esegui "if /?" sulla riga di comando per i dettagli


5
Questo vedrà solo se esiste un file / directory con quel nome nella directory corrente. Non fornisce molti indizi sull'esistenza di un comando eseguibile con quel nome perché per determinare che dovresti cercare PATH.
Joey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.