Bir toplu iş dosyasında komutun tanınıp tanınmayacağını belirleme


43

İçinde bir programı (javac gibi) çağırdığım bir yarasa komut dosyası yazıyorum. Basit olması için, çalıştırmadan önce komutun var olup olmadığını kontrol etmek istiyorum. yani eğer komut PATH'ta mevcutsa.

Örneğin,

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
)

Bunu Windows'ta yapmanın en iyi yolu nedir?


Emrinizi nasıl "tanıyacaksınız"?
Rook

MS-DOS'ta (gerçek DOS) bu oldukça basitti; Bir exe dosyasının varlığını c: \ dos; ama o zaman bile soru kalıyor.
Rook

Karışıklık için özür dilerim. Esasen Windows'ta bir komut istemi demek istemiştim. "Lkajsflksajdfj" yazarsanız, bunun bir komut olmadığını tespit etmek isterim. "Notepad.exe" yazarsanız, sorun yok.
user46097,

Yanıtlar:


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

10
Birisi cmd penceresindeki çıktıyı istemiyorsa, sadece >nul 2>nularkasını ekleyin mycommand.
Sebastian,

1 ve 2'den daha fazla çıkış kanalı bulunduğunu unutmayın; çünkü 1, çıkış arabelleğini, 2 ise hata arabelleğini gösterir, uygulamanın nasıl geliştirildiğine bağlıdır, Windows ile birlikte gelen ortak uygulamalar için çalışmalıdır, ancak belirli bir CLI programı olabilir. Kanal 1 ve 2 yönlendirildiğinde hala metin atıyor.
ElektroStudios

15

Aşağıdaki kod her zaman atık çıkışı olmadan temiz bir şekilde yürütülmelidir.

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

Çıktı:

found javac

Tek astar ile aynı kod:

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

Çıktı:

fail

Bu düzen içinde dikkat &&ve ||önemi gibi görünüyor. Ayrıca, varlığı için test ettiğiniz komutun çalışması için <= 0 hata düzeyiyle dönmesi gerekir. Umarım komut / vardır? veya --help argümanları veya java'da olduğu gibi, version info komutu.


Bu çözüm mükemmel!
robe007

7

En kolay yol, komutu basitçe çalıştırmaktır, ancak elbette, rastgele bir işlem başlatmak istemeyeceğiniz için elbette başka sorunları var.

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

%PATH%çevre değişkeni tarafından listelenen yollarda programı arayan bir alternatiftir . Esasen saf bir toplu sürümü which(1). Daha iyi yapılabilir ama aslında budur.


1
Bu mükemmel, tam olarak ne isteniyorsa onu yapıyor!
Pez Cuckow

3

Benim durumum için. Mutlak en basit yol || veya && operatörü.

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

veya

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

Neden stdout'u da yönlendirmiyorsun?
Joey,

3

Aşağıdaki sürümde bazı iyileştirmeler. Bu komutun mevcut olduğunu test edin ve gereksiz çıktıları bastırın.

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

<my_exe> NUL 2> & 1 || echo my.exe mevcut değil & & git: EOF komut dosyalarında iyi çalışıyor
Robert

Not: Bu, test etmek istediğiniz dosya adı yol bilgisi içeriyorsa çalışmaz. Örneğin, WHERE \Windows\System32\cmd.exe=>INFO: Could not find files for the given pattern(s).
Jonathan Gilbert

1

Ekstra araçların kurulmasını gerektiriyorsa sorun yok, wherekaynak kitlerinde bir komut var ; whereis eşdeğer Windows görmek ? .

Aksi takdirde, çok eski olmayan Windows sürümleri için cmd, PATH dışında Dos çalıştırılabilir araması bölümünde belirtildiği gibi saf olarak yapılabilir .


Cevap için teşekkürler! Ne yazık ki, gereksinimlerden biri, vanilya kutusu (XP makineleri dahil) üzerinde çalışması gerektiğidir - bu yüzden nerede bir seçenek değildir.
user46097

2
Gilles'un verdiği ikinci bağlantı, FOR kullanan ve fazladan araç kullanmayan şık bir çözüme sahiptir.
paradroid

1

Bunun aradığınızı tam olarak bilmediğimi biliyorum, ancak mantıktaki ufak bir değişiklikle ihtiyacınız olanı başarması gerekir.

Çalıştırılan her komutun bir dönüş kodu (aka errorlevel) vardır, dönüş kodu 0 (sıfır) ise, komut başarıyla çalıştırılır, dönüş kodu 0'dan büyükse, bir şeyler ters gitti.

Daha fazla bilgi için buraya bakınız.

Gibi bir şey -

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
)

Bu akıllıca, hoşuma gitti.
Shinrai,

Evet, ama çirkindir, eğer komut bulunmazsa 2 satırlık bir hata verir. Böylece, muhtemelen daha temiz bir çözüm bulunabilir.
djangofan

0

Tüm bu yollar işe yarayabilirken, neden yerleşik değil?

If exists my_command do echo "my_command exists"

"İf /?" Komutunu çalıştırın Ayrıntılar için komut satırında


5
Bu, sadece bu isimde bir dosya / dizinin mevcut dizinde bulunup bulunmadığına bakacaktır. Bu adla çalıştırılabilir bir komutun olup olmadığına dair pek bir ipucu vermez, çünkü aramak zorunda kalacağınızı belirlemek için PATH.
Joey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.