Menentukan apakah perintah dikenali dalam file batch

43

Saya sedang menulis skrip kelelawar di mana saya menjalankan program (seperti javac). Untuk kesederhanaan, saya ingin memeriksa apakah ada perintah sebelum saya menjalankannya. yaitu Jika perintah ada di PATH.

Sebagai contoh,

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
)

Apa cara terbaik untuk melakukan ini di Windows?

pengguna46097
sumber
Bagaimana Anda akan "mengenali" perintah Anda?
Benteng
Dalam MS-DOS (true DOS) ini agak sederhana; Anda baru saja memeriksa keberadaan file exe di c: \ dos; tapi meski begitu pertanyaannya tetap.
Benteng
Maaf bila membingungkan. Maksud saya pada dasarnya prompt perintah di Windows. Jika saya mengetik "lkajsflksajdfj" saya ingin mendeteksi itu bukan perintah. Jika saya mengetik "notepad.exe", tidak apa-apa.
user46097

Jawaban:

54
WHERE mycommand
IF %ERRORLEVEL% NEQ 0 ECHO mycommand wasn't found 
Josh Santangelo
sumber
10
Jika seseorang tidak ingin output di dalam jendela cmd tambahkan saja di >nul 2>nulbelakang mycommand.
Sebastian
Perhatikan bahwa ada lebih banyak saluran output daripada 1 dan 2, karena 1 berarti buffer output dan 2 untuk buffer kesalahan, itu tergantung pada bagaimana aplikasi dikembangkan, itu harus bekerja untuk aplikasi umum yang dikirimkan bersama Windows, tetapi program CLI tertentu bisa masih melempar teks ketika saluran 1 dan 2 dialihkan.
ElektroStudios
15

Kode di bawah ini harus selalu dijalankan dengan bersih tanpa keluaran sampah.

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

Keluaran:

found javac

Kode yang sama dengan one-liner:

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

Keluaran:

fail

Perhatikan bahwa urutan &&dan ||tampaknya penting. Juga, perintah yang keberadaannya Anda uji perlu kembali dengan tingkat kesalahan <= 0 agar ini berfungsi. Semoga perintahnya memiliki /? atau --help argumen atau, seperti java, perintah info versi.

ngreen
sumber
Solusi ini sempurna!
robe007
7

Cara termudah adalah dengan hanya menjalankan perintah, tetapi itu memiliki masalah lain, tentu saja, karena mungkin Anda tidak ingin memulai proses acak.

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

adalah alternatif yang mencari program di jalur yang terdaftar oleh %PATH%variabel lingkungan. Ini pada dasarnya versi batch murni which(1). Itu bisa dibuat lebih baik tetapi pada dasarnya ini dia.

Joey
sumber
1
Ini sempurna, tidak persis apa yang diminta!
Pez Cuckow
3

Untuk situasi saya. Cara termudah mutlak adalah menggunakan || atau && operator.

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

atau

my_command.exe -version 2>NUL || echo "my_command doesn't exist"
pengguna46097
sumber
Mengapa Anda tidak mengarahkan stdout juga?
Joey
3

Beberapa penyempurnaan untuk versi di bawah ini. Uji bahwa ada perintah dan tekan output yang tidak dibutuhkan.

WHERE scp >nul 2>nul
IF %ERRORLEVEL% EQU 0 ECHO scp found
yuliskov
sumber
di mana <my_exe> NUL 2> & 1 || echo my.exe tidak ada && goto: EOF bekerja dengan baik dalam skrip
Robert
NB: Ini tidak berfungsi jika nama file yang ingin Anda uji menyertakan informasi jalur. Misalnya, WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Jonathan Gilbert
1

Jika membutuhkan pemasangan alat tambahan tidak masalah, ada whereperintah dalam kit sumber daya; lihat padanan Windows di mana? .

Kalau tidak, untuk versi Windows yang tidak terlalu kuno, itu bisa dilakukan secara murni cmd, seperti yang disebutkan dalam Dos executable lookup kecuali PATH .

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih atas tanggapannya! Sayangnya, salah satu persyaratannya adalah harus dijalankan pada kotak vanilla (termasuk mesin XP) - jadi di mana bukan merupakan pilihan.
user46097
2
Tautan kedua yang diberikan Gilles memiliki solusi bagus yang menggunakan FOR dan tidak ada alat tambahan.
paradroid
1

Saya tahu ini tidak cukup apa yang Anda cari, tetapi dengan sedikit perubahan dalam logika itu harus memenuhi apa yang Anda butuhkan.

Setiap perintah yang dijalankan memiliki kode kembali (alias errorlevel), jika kode kembali adalah 0 (nol), perintah telah berhasil dijalankan, jika kode kembali lebih besar dari 0, ada yang salah.

Lihat di sini untuk detail lebih lanjut.

Sesuatu seperti -

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
sumber
Ini pintar, saya menyukainya.
Shinrai
Ya, tapi itu jelek karena, jika perintah tidak ditemukan itu melempar kesalahan 2 baris. Jadi, solusi yang lebih bersih dapat ditemukan.
Djangofan
0

Sementara semua cara itu mungkin berhasil, mengapa tidak dibangun di jalan?

If exists my_command do echo "my_command exists"

Jalankan "jika /?" pada baris perintah untuk detail

uSlackr
sumber
5
Ini hanya akan melihat apakah file / direktori dengan nama itu ada di direktori saat ini. Ini tidak memberikan banyak petunjuk apakah perintah runnable dengan nama itu ada karena untuk menentukan bahwa Anda harus mencari PATH.
Joey