Sprawdź, czy polecenie jest rozpoznawane w pliku wsadowym

43

Piszę skrypt nietoperza, w którym wywołuję program (na przykład javac). Dla uproszczenia chcę sprawdzić, czy polecenie istnieje przed jego uruchomieniem. tzn. jeśli polecenie istnieje w zmiennej PATH.

Na przykład,

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
)

Jak najlepiej to zrobić w systemie Windows?

użytkownik46097
źródło
Jak „rozpoznasz” swoje polecenie?
Wieża
W MS-DOS (prawdziwy DOS) było to dość proste; właśnie sprawdziłeś istnienie pliku exe w c: \ dos; ale nawet wtedy pozostaje pytanie.
Gawron
Przepraszam za zamieszanie. Miałem zasadniczo na myśli wiersz poleceń w systemie Windows. Jeśli wpiszesz „lkajsflksajdfj”, chcę wykryć, że nie jest to polecenie. Jeśli wpiszesz „notepad.exe”, to będzie OK.
user46097,

Odpowiedzi:

54
WHERE mycommand
IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 
Josh Santangelo
źródło
10
Jeśli ktoś nie chce danych wyjściowych w oknie cmd, po prostu dodaj >nul 2>nulza mycommand.
Sebastian,
Pamiętaj, że jest więcej kanałów wyjściowych niż 1 i 2, ponieważ 1 oznacza bufor wyjściowy, a 2 bufor błędów, zależy to od sposobu opracowania aplikacji, powinna działać dla popularnych aplikacji dostarczanych z systemem Windows, ale konkretny program CLI może wciąż rzuca tekst, gdy kanały 1 i 2 są przekierowane.
ElektroStudios
15

Poniższy kod powinien zawsze być wykonywany czysto, bez żadnych śmieci.

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

Wynik:

found javac

Ten sam kod jak w jednej linijce:

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

Wynik:

fail

Zauważ, że kolejność &&i ||wydaje się mieć znaczenie. Aby polecenie zadziałało, polecenie, którego istnienie testujesz, musi powrócić z poziomem błędu <= 0. Mam nadzieję, że polecenie ma /? lub --help argumenty lub, podobnie jak w Javie, polecenie informacji o wersji.

ngreen
źródło
To rozwiązanie jest idealne!
robe007
7

Najłatwiej jest po prostu uruchomić polecenie, ale ma to oczywiście inne problemy, ponieważ być może nie chcesz, aby proces był uruchamiany losowo.

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

jest alternatywą, która wyszukuje program na ścieżkach wymienionych przez %PATH%zmienną środowiskową. Jest to w zasadzie czysta wersja partii which(1). Można to ulepszyć, ale w gruncie rzeczy to jest to.

Joey
źródło
1
To jest idealne, robi dokładnie to, o co proszono!
Pez Cuckow
3

Do mojej sytuacji. Absolutnie najprostszym sposobem jest użycie || lub operator &&.

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

lub

my_command.exe -version 2>NUL || echo "my_command doesn't exist"
użytkownik46097
źródło
Dlaczego też nie przekierowujesz standardowego wyjścia?
Joey,
3

Niektóre udoskonalenia wersji poniżej. Sprawdź, czy polecenie to istnieje i pomiń niepotrzebne dane wyjściowe.

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found
Juliskov
źródło
gdzie <my_exe> NUL 2> i 1 || echo my.exe nie istnieje && goto: EOF działa dobrze w skryptach
Robert
Uwaga: To nie działa, jeśli nazwa pliku, który chcesz przetestować, zawiera informacje o ścieżce. Np. WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Jonathan Gilbert
1

Jeśli wymaganie instalacji dodatkowych narzędzi jest w porządku, wherew zestawach zasobów znajduje się polecenie; zobaczyć Windows odpowiednik whereis? .

W przeciwnym razie dla wersji systemu Windows, które nie są zbyt stare, można to zrobić w czystej postaci cmd, jak wspomniano w wyszukiwaniu wykonywalnym Dos, z wyjątkiem PATH .

Gilles „SO- przestań być zły”
źródło
Dzięki za odpowiedź! Niestety, jednym z wymagań jest to, że musi on działać na waniliowym pudełku (w tym maszyny XP) - więc gdzie nie ma takiej opcji.
user46097,
2
Drugi link, który podał Gilles, zawiera ciekawe rozwiązanie, które używa FOR i żadnych dodatkowych narzędzi.
paradroid,
1

Wiem, że nie do końca tego szukasz, ale z niewielką zmianą logiki powinno ono osiągnąć to, czego potrzebujesz.

Każde uruchamiane polecenie ma kod powrotu (inaczej poziom błędu), jeśli kod powrotu to 0 (zero), polecenie zostało wykonane pomyślnie, jeśli kod powrotu jest większy niż 0, coś poszło nie tak.

Zobacz tutaj po więcej szczegółów.

Coś jak -

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
źródło
To sprytne, podoba mi się.
Shinrai,
Tak, ale jest to brzydkie, ponieważ jeśli polecenie nie zostanie znalezione, zgłasza błąd 2 linii. Zatem możliwe jest znalezienie czystszego rozwiązania.
djangofan
0

Chociaż wszystkie te sposoby mogą działać, dlaczego nie wbudowane?

If exists my_command do echo "my_command exists"

Uruchom „if /?” w wierszu polecenia, aby uzyskać szczegółowe informacje

uSlackr
źródło
5
Spowoduje to tylko sprawdzenie, czy plik / katalog o tej nazwie istnieje w bieżącym katalogu. Nie daje wiele wskazówek, czy istnieje komenda uruchamialna o takiej nazwie, ponieważ w celu ustalenia, że ​​należy przeszukać PATH.
Joey,