Xác định xem lệnh có được nhận ra trong tệp bó không


43

Tôi đang viết một kịch bản bat trong đó tôi gọi một chương trình (chẳng hạn như javac). Để đơn giản, tôi muốn kiểm tra xem lệnh có tồn tại trước khi tôi chạy nó không. tức là nếu lệnh tồn tại trong PATH.

Ví dụ,

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
)

Cách tốt nhất để làm điều này trong Windows là gì?


Làm thế nào bạn sẽ "nhận ra" lệnh của bạn?
Rook

Trong MS-DOS (DOS thực sự) điều này khá đơn giản; bạn vừa kiểm tra sự tồn tại của tệp exe trong c: \ dos; nhưng ngay cả sau đó câu hỏi vẫn còn.
Rook

Xin lỗi vì sự nhầm lẫn. Ý tôi là về cơ bản là một dấu nhắc lệnh trong Windows. Nếu tôi gõ "lkajsflksajdfj" tôi muốn phát hiện ra đó không phải là một lệnh. Nếu tôi gõ "notepad.exe" thì không sao.
user46097

Câu trả lời:


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

10
Nếu ai đó không muốn đầu ra bên trong cửa sổ cmd, chỉ cần thêm >nul 2>nulphía sau mycommand.
Sebastian

Lưu ý rằng có nhiều kênh đầu ra hơn 1 và 2, vì 1 là viết tắt của bộ đệm đầu ra và 2 cho bộ đệm lỗi, nó phụ thuộc vào cách ứng dụng được phát triển, nó sẽ hoạt động cho các ứng dụng phổ biến đi kèm với Windows, nhưng một chương trình CLI cụ thể có thể vẫn ném văn bản khi các kênh 1 và 2 được chuyển hướng.
ElektroStudios

15

Mã dưới đây phải luôn luôn thực thi sạch sẽ không có đầu ra rác.

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

Đầu ra:

found javac

Mã giống như một lớp lót:

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

Đầu ra:

fail

Lưu ý rằng thứ tự &&||dường như có vấn đề. Ngoài ra, lệnh mà sự tồn tại của bạn đang kiểm tra cần phải trả về với một lỗi <= 0 để nó hoạt động. Hy vọng lệnh có /? hoặc - trợ giúp đối số hoặc, như với java, lệnh thông tin phiên bản.


Giải pháp này là hoàn hảo!
robe007

7

Cách đơn giản nhất là chỉ cần chạy lệnh, nhưng điều đó có vấn đề khác, tất nhiên, vì có thể bạn không muốn có một quá trình ngẫu nhiên bắt đầu.

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

là một thay thế tìm kiếm chương trình trong các đường dẫn được liệt kê bởi %PATH%biến môi trường. Đây thực chất là một phiên bản thuần túy của which(1). Nó có thể được làm tốt hơn nhưng về cơ bản đây là nó.


1
Điều này là hoàn hảo, làm chính xác những gì được yêu cầu!
Pez Cuckow

3

Đối với tình hình của tôi. Cách đơn giản nhất tuyệt đối là sử dụng | | hoặc && toán tử.

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

hoặc là

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

Tại sao bạn không chuyển hướng thiết bị xuất chuẩn quá?
Joey

3

Một số tinh chỉnh cho phiên bản dưới đây. Kiểm tra lệnh đó tồn tại và triệt tiêu đầu ra không cần thiết.

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

trong đó <my_exe> NUL 2> & 1 || echo my.exe không tồn tại && goto: EOF hoạt động độc đáo trong các tập lệnh
Robert

NB: Điều này không hoạt động nếu tên tệp bạn muốn kiểm tra bao gồm thông tin đường dẫn. Ví dụ: WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Jonathan Gilbert

1

Nếu yêu cầu cài đặt các công cụ bổ sung là ok, có một wherelệnh trong bộ tài nguyên; Xem Windows tương đương với đâu? .

Mặt khác, đối với các phiên bản Windows không quá cũ, nó hoàn toàn có thể thực hiện được cmd, như được đề cập trong tra cứu thực thi Dos ngoại trừ PATH .


Cảm ơn phản hồi! Thật không may, một trong những yêu cầu là nó phải chạy trên hộp vanilla (bao gồm máy XP) - vì vậy đây không phải là một tùy chọn.
user46097

2
Liên kết thứ hai mà Gilles đưa ra có một giải pháp tiện lợi sử dụng FOR và không có công cụ bổ sung.
paradroid

1

Tôi biết điều này không hoàn toàn là những gì bạn đang tìm kiếm, nhưng với một chút thay đổi trong logic, nó sẽ hoàn thành những gì bạn cần.

Mỗi lệnh được chạy đều có mã trả về (còn gọi là errorlevel), nếu mã trả về là 0 (không), lệnh đã chạy thành công, nếu mã trả về lớn hơn 0, đã xảy ra lỗi.

Xem ở đây để biết thêm chi tiết.

Cái gì đó như -

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
)

Điều này là thông minh, tôi thích nó.
Shinrai

Vâng, nhưng nó xấu, vì nếu không tìm thấy lệnh, nó sẽ ném lỗi 2 dòng. Vì vậy, một giải pháp sạch hơn có thể được tìm thấy có thể.
djangofan

0

Trong khi tất cả những cách đó có thể hoạt động, tại sao không được xây dựng theo cách?

If exists my_command do echo "my_command exists"

Chạy "nếu /?" trên dòng lệnh để biết chi tiết


5
Điều này sẽ chỉ xem liệu một tập tin / thư mục có tên đó tồn tại trong thư mục hiện tại. Nó không cung cấp nhiều gợi ý cho dù một lệnh có thể chạy được với tên đó tồn tại hay không bởi vì để xác định rằng bạn phải tìm kiếm PATH.
Joey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.