Определить, распознана ли команда в командном файле

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?

user46097
источник
Как вы «узнаете» свою команду?
Ладья
В MS-DOS (настоящая DOS) это было довольно просто; Вы только что проверили наличие exe-файла в c: \ dos; но даже тогда вопрос остается.
Ладья
Извините за путаницу. Я имел ввиду по существу командную строку в Windows. Если я наберу "lkajsflksajdfj", я хочу обнаружить, что это не команда. Если я наберу "notepad.exe", все в порядке.
user46097

Ответы:

53
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
14

Приведенный ниже код всегда должен выполняться чисто, без вывода мусора.

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

Выход:

found javac

Тот же код, что и в одной строке:

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

Выход:

fail

Обратите внимание, что порядок &&и, ||кажется, имеет значение. Кроме того, команда, существование которой вы проверяете, должна возвращаться с уровнем ошибки <= 0, чтобы это работало. Надеюсь, команда имеет /? или аргументы --help, или, как и в случае с Java, команду информации о версии.

ngreen
источник
Это решение идеально!
robe007
7

Самый простой способ - просто запустить команду, но у нее, конечно, есть другие проблемы, поскольку, возможно, вы не хотите запускать случайный процесс.

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

альтернатива, которая ищет программу по путям, указанным в %PATH%переменной среды. Это по сути чистая пакетная версия which(1). Это можно сделать лучше, но по сути это так.

детеныш
источник
1
Это прекрасно, делает именно то, что просили!
Pez Cuckow
3

Некоторые уточнения к версии ниже. Проверьте, существует ли эта команда, и отключите ненужные выходные данные.

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found
yuliskov
источник
где <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).
Джонатан Гилберт
2

Для моей ситуации. Абсолютно простым способом является использование || или && оператор.

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

или же

my_command.exe -version 2>NUL || echo "my_command doesn't exist"
user46097
источник
Почему бы вам не перенаправить стандартный вывод?
Джои
1

Если требуется установка дополнительных инструментов, в наборе whereресурсов есть команда; увидеть Windows эквивалент где? ,

В противном случае для версий Windows, которые не являются слишком древними, это можно сделать в чистом виде cmd, как упоминалось в поиске исполняемых файлов Dos, за исключением PATH .

жилль
источник
Спасибо за ответ! К сожалению, одно из требований заключается в том, что он должен работать на ванильном боксе (включая компьютеры с XP) - так что это не вариант.
user46097
2
Вторая ссылка, которую дал Жиль, имеет изящное решение, которое использует FOR и не требует дополнительных инструментов.
парадроид
1

Я знаю, что это не совсем то, что вы ищете, но с небольшим изменением в логике это должно выполнить то, что вам нужно.

Каждая выполняемая команда имеет код возврата (он же уровень ошибки), если код возврата равен 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
)
Bryan
источник
Это умно, мне это нравится.
Shinrai
Да, но это ужасно, поскольку, если команда не найдена, она выдает ошибку в 2 строки. Таким образом, может быть найдено более чистое решение.
Джангофан
0

Хотя все эти пути могут работать, почему не встроенный способ?

If exists my_command do echo "my_command exists"

Запустите "если /?" в командной строке для деталей

uSlackr
источник
5
Это будет только посмотреть, существует ли файл / каталог с таким именем в текущем каталоге. Это не дает большой подсказки, существует ли работающая команда с таким именем, потому что для определения того, что вам нужно искать PATH.
Джои