Визначте, чи розпізнається команда у пакетному файлі


43

Я пишу сценарій bat, в якому я викликаю програму (наприклад, javac). Для простоти я хочу перевірити, чи існує команда, перш ніж її запустити. тобто якщо команда існує в PATH.

Наприклад,

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
)

Який найкращий спосіб зробити це в Windows?


Як ви "розпізнаєте" свою команду?
Грак

У MS-DOS (справжній DOS) це було досить просто; Ви щойно перевірили наявність exe-файлу в c: \ dos; але навіть тоді питання залишається.
Грак

Вибачте за непорозуміння. Я по суті мав на увазі командний рядок в Windows. Якщо я набираю "lkajsflksajdfj", я хочу виявити, що це не команда. Якщо я набираю "notepad.exe", це нормально.
user46097

Відповіді:


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

10
Якщо хтось не хоче, щоб результат у вікні cmd просто додати >nul 2>nulза mycommand.
Себастьян

Зауважте, що вихідних каналів більше, ніж 1 і 2, оскільки 1 означає вихідний буфер, а 2 - буфер помилок, це залежить від того, як розроблялася програма, вона повинна працювати для звичайних додатків, що постачаються з Windows, але конкретна програма CLI могла б все ще кидає текст, коли канали 1 і 2 переспрямовуються.
ElektroStudios

15

Код, наведений нижче, завжди повинен виконуватись чисто і без сміття.

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

Вихід:

found javac

Той самий код, що і однолінійний:

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

Вихід:

fail

Зауважте, що порядок &&і, ||здається, має значення. Також команда, існування якої ви протестуєте, потребує повернення з рівнем помилок <= 0, щоб це працювало. Сподіваємось, команда має /? або - допомогти аргументам або, як у Java, команді інформації про версію.


Це рішення ідеально!
robe007

7

Найпростіший спосіб - це просто запустити команду, але, звичайно, є й інші проблеми, оскільки, можливо, ви не хочете запускати випадковий процес.

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

це альтернатива, яка шукає програму в шляхах, перелічених %PATH%змінною оточення. Це по суті чиста пакетна версія which(1). Це можна зробити краще, але по суті це все.


1
Це ідеально, робить саме те, що просили!
Pez Cuckow

3

Для моєї ситуації. Абсолютно найпростішим способом є використання || або оператора &&

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

або

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

Чому ви також не перенаправляєте stdout?
Joey

3

Деякі вдосконалення до версії нижче. Перевірте, чи існує така команда, і придушіть непотрібний вихід.

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

де <my_exe> NUL 2> & 1 || echo my.exe не існує && goto: EOF чудово працює в сценаріях
Роберт

Примітка: Це не працює, якщо ім'я файлу, яке ви хочете перевірити, включає інформацію про шлях. Наприклад, WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Джонатан Гілберт

1

Якщо вимагає встановлення додаткових інструментів, нормально, whereв наборах ресурсів є команда; див. еквівалент Windows для чого? .

В іншому випадку, для версій Windows, які не надто давні, це можна виконати в чистому режимі cmd, як це було зазначено в Dos-виконавчому пошуку за винятком PATH .


Дякую за відгук! На жаль, одна з вимог полягає в тому, що він повинен працювати на ванільній коробці (в комплекті з машинами XP) - тож це не варіант.
user46097

2
Друга посилання, яку надав Жиль, має чудове рішення, яке використовує FOR і не потребує додаткових інструментів.
парадороїд

1

Я знаю, що це не зовсім те, що ви шукаєте, але при незначній зміні логіки воно повинно досягти того, що вам потрібно.

Кожна команда, що виконується, має код повернення (aka errorlevel), якщо код повернення дорівнює 0 (нуль), команда успішно виконується, якщо код повернення більше 0, щось пішло не так.

Дивіться тут для більш детальної інформації.

Щось на зразок -

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
)

Це розумно, мені це подобається.
Shinrai

Так, але це некрасиво, оскільки, якщо команда не знайдена, вона видає помилку в 2 рядку. Тож, можливо, було знайдено більш чисте рішення.
djangofan

0

Хоча все це може працювати, чому б не побудований спосіб?

If exists my_command do echo "my_command exists"

Виконати "якщо /?" у командному рядку для отримання детальної інформації


5
Це буде виглядати лише, чи існує файл / каталог з цим ім'ям у поточному каталозі. Це не дуже натякає на те, чи існує команда, яку можна виконати з цим ім'ям, тому що для визначення того, що вам доведеться шукати PATH.
Joey
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.