Bir .BAT dosyasında birden çok .BAT dosyası nasıl çalıştırılır


695

commit-build.batOluşturma sürecimizin bir parçası olarak diğer .BAT dosyalarını yürütmeye çalışıyorum .

İçeriği commit-build.bat:

"msbuild.bat"
"unit-tests.bat"
"deploy.bat"

Bu yeterince basit görünüyor, ancak commit-build.batlistedeki ( msbuild.bat) yalnızca ilk öğeyi yürütüyor .

Her dosyayı ayrı ayrı sorunsuz çalıştırdım.


4
@sean - Komut satırı araçlarının çalışmasını sağlamak için tam Cygwin paketini yüklemeniz gerekmez. Sadece tüm cygwin dll'leri paketlenmiş bir dizine yerleştirin, tüm araçlarınızı başka bir dizine koyun ve gitmekte fayda var.
Techie Joe

bu dosyaların her birinin yalnızca toplu olduğunu varsayarsak, onları neden sadece büyük bir dosyaya koyup her seferinde başlatmak için zaman aşımı işlevini kullanmıyorsunuz.
CMS_95

Yanıtlar:


1201

kullanın:

call msbuild.bat
call unit-tests.bat
call deploy.bat

CALL kullanılmadığında, geçerli toplu iş dosyası durur ve çağrılan toplu iş dosyası yürütülmeye başlar. MS-DOS'un ilk günlerine kadar uzanan tuhaf bir davranış.


garip, ben windows 7 "çağrı" olmadan denedim ve işe yaradığını hatırlıyorum, ama windows xp bu komutu gerekli. olabilir mi?
android geliştirici

7
Çağrı olmadan, orijinal DOS spec başına, komut zincirleme yapmalı ve geri dönmemelidir. "CALL" eklenmeden önceki popüler bir seçenek de "command / c second.bat" gibi bir alt komut istemi açmaktı.
Brian Knoblauch

1
Windows 7 girişiminde sorun yaşadım, bu yüzden sadece xp değil
Rafiki

7
Windows 10'da yalnızca ilk satır yürütülür. Farheen'in cevabı işe yaradı.
17bro

2
Parametrelerin toplu iş dosyalarına geçirilmesi ve parametrelerden biri boşluklu bir yoldur.
Zeus

180

Diğer tüm cevaplar doğrudur: çağrıyı kullanın. Örneğin:

 call "msbuild.bat"

Tarih

Eski DOS sürümlerinde, toplu iş dosyalarını yinelemeli olarak yürütmek mümkün değildi. Daha sonra, toplu iş dosyasını yürütmek için başka bir cmd kabuğu çağıran ve bittiğinde yürütme cmd kabuğuna yürütmeyi döndüren çağrı komutu tanıtıldı.

Açıkçası daha sonraki versiyonlarda artık başka bir cmd kabuğu gerekli değildi.

İlk günlerde birçok toplu iş dosyası, bir toplu iş dosyasını çağırmanın çağrılan toplu iş dosyasına dönmeyeceğine bağlıydı. Ek sözdizimi olmadan bu davranışı değiştirmek, toplu menü sistemleri (menü yapıları için toplu iş dosyalarını kullanma) gibi birçok sistemi bozacaktır.

Microsoft'ta olduğu gibi birçok durumda olduğu gibi, bu davranışın nedeni geriye dönük uyumluluktur.

İpuçları

Toplu iş dosyalarınızın adlarında boşluk varsa, adın çevresinde tırnak işareti kullanın:

call "unit tests.bat"

Bu arada: toplu iş dosyalarının tüm adlarına sahip değilseniz, bunu yapmak için de kullanabilirsiniz (toplu dosya çağrılarının doğru sırasını garanti etmez; dosya sisteminin sırasını izler):

FOR %x IN (*.bat) DO call "%x"

Bir çağrıdan sonra hata düzeylerine de tepki verebilirsiniz. kullanın:

exit /B 1   # Or any other integer value in 0..255

bir hata seviyesi geri vermek. 0 doğru yürütmeyi belirtir. Çağıran toplu iş dosyasında aşağıdakileri kullanarak yanıt verebilirsiniz:

if errorlevel neq 0 <batch command>

if errorlevel 1Tüm hata düzeylerini 1 ve üstünü yakalamak için NT4 / 2000 / XP'den daha eski bir Windows'unuz varsa kullanın .

Bir toplu iş dosyasının akışını denetlemek için goto :-( var

if errorlevel 2 goto label2
if errorlevel 1 goto label1
...
:label1
...
:label2
...

Diğerlerinin belirttiği gibi: toplu iş dosyalarını değiştirmek için derleme sistemlerine göz atın.


kabul etti, ancak döngü, bu durumda, dosyaları yanlış (alfabetik?) sırada işleyebilir
Dave Archer

Güzel ve çok eksiksiz bir cevap. Kontrol akışını dahil ediyorsanız, goto yerine, call: label1 komutunu kullanarak alt yordamlar yapabileceğinizi ve toplu iş dosyalarındaki 'return' ifadesinin biraz garip goto: eof (ve varsayılan olarak var olan bir etiket etiketi oluşturun).
Legolas

errorlevelKomut örneği (cmd konsolunda), Windows 10 Bana bir sorunla verdi. Komutu basitçe olacak şekilde değiştirdim if errorlevel neq echo Houston We have a Problem!. Toplu işlemimde herhangi bir sorun olmadı ve çoğunlukla normal olarak tamamlandı, ancak bir çağrı ifadesinden sonra bu komutu kullandığım yolun her adımı "şu anda neq beklenmedikti" aldım. Eşit olmayan sözdizimini değiştirmiş olabileceğini düşünerek denedim !=ve aynı zamanda <>yeni sözdizimi için aynı "şu anda beklenmeyen" hatası almaya devam ettim . neyi yanlış yapabilirdim?
TMWP

118

Birden fazla komut istemi açmak istiyorsak,

start cmd /k

/k: yürütmek zorunludur.

Birçok komut isteminin başlatılması aşağıdaki gibi yapılabilir.

start cmd /k Call rc_hub.bat 4444

start cmd /k Call rc_grid1.bat 5555

start cmd /k Call rc_grid1.bat 6666

start cmd /k Call rc_grid1.bat 5570.

7
ilk uygulamamız konsolu engellediği için aradığımız şey bu, ipucu için teşekkürler
Michael Moeller

1
bu, birden fazla komut örneği çalıştırır ve hatta <pause> içeren birden çok toplu iş dosyasını çalıştırmak için bile çalışır. +1 tam olarak aradığım çözüm olduğu için!
Christian Noel

5
Lütfen bu rakamların cevabınızda olduğunu açıklar mısınız? Amaçları net değil.
Kalamalka Kid

3
Çoğu insanın bir start "Window title" /wait cmd /k call something.batşeyleri sırayla çalıştırmak için muhtemelen kullanmak istediğini unutmayın .
Andrew

3
(veya start "Window title" /wait cmd /c something.batnerede cmd /cbitmiş bir kez pencereyi kapatır)
Andrew

42

Deneyin:

call msbuild.bat
call unit-tests.bat
call deploy.bat

28

Bir programı derlemek için birden çok toplu iş çağırıyorsunuz. Bir hata oluşursa:
1) Parti içindeki program bir hata seviyesi ile çıkacak;
2) Bunu bilmek istiyorsun.

for %%b in ("msbuild.bat" "unit-tests.bat" "deploy.bat") do call %%b|| exit /b 1

'||' 0'dan daha yüksek bir hata seviyesi test eder. Bu şekilde tüm gruplar sırayla çağrılır, ancak herhangi bir hata durumunda durur ve ekranı herhangi bir hata mesajı görmeniz için olduğu gibi bırakır.


23

İki toplu komut dosyamız varsa, aaa.bat ve bbb.bat ve aşağıdaki gibi arayın

call aaa.bat
call bbb.bat

Komut dosyasını yürütürken, önce aaa.bat öğesini çağırır, aaa.bat sonlandırmasının iş parçacığını bekler ve bbb.bat öğesini çağırır.

Ancak aaa.bat dosyasının bbb.bat aramasını sonlandırmasını beklemek istemiyorsanız, START komutunu kullanmayı deneyin :

START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
  [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
  [/AFFINITY <hex affinity>] [/WAIT] [/B] [command/program]
  [parameters]

Sınav:

start /b aaa.bat
start /b bbb.bat


20

.batDosya içindeki bir .batdosyayı aramak için şunu kullanın:

call foo.bat

(Evet, bu aptalca, foo.batkomut isteminde olduğu gibi arayabiliyorsanız daha mantıklı olurdu , ancak doğru yol kullanmaktır call.)


7

Dosya adlarınıza bakarak NAnt veya Ant (Java sürümü) gibi bir oluşturma aracı kullanmayı düşündünüz mü ? Yarasa dosyalarıyla olduğundan çok daha fazla kontrole sahip olacaksınız.


7

Aynı anda çok sayıda toplu iş dosyasını açmak istiyorsanız, call komutunu kullanabilirsiniz. Ancak, call komutu geçerli yarasa dosyasını kapatır ve diğerine gider. Bir kerede çok sayıda açmak istiyorsanız, bunu denemek isteyebilirsiniz:

@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"

Ve böyle devam edin veya birçok dosyayı "" cmd" tekrarlayın call. Bu Windows 7 için çalışıyor , ancak diğer sistemlerden emin değilim.


6
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat

Bu işe yaramazsa, start ile callveya bu deneyin:

Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat

3

Sadece callkomutu kullanın! İşte bir örnek:

call msbuild.bat
call unit-tests.bat
call deploy.bat

3

Doğru alıntı ile (bu bazen zor olabilir):

start "" /D "C:\Program Files\ProgramToLaunch" "cmd.exe" "/c call ""C:\Program Files\ProgramToLaunch\programname.bat"""

1. arg - Başlık (bu durumda boş)
2. arg - / D başlangıç ​​dizinini belirtir, geçerli çalışma dizinini ("% ~ dp0" gibi) isterseniz
3. arg - başlatma komutu "cmd.exe"
4th arg - içindeki bağımsız değişkenler için ikiye katlanmış tırnaklarla komut verilecek argümanlar (toplu olarak tırnak içinde tırnaklardan nasıl kaçarsınız)


2

Birden fazla komut dosyası çalıştırırken aynı sorunu yaşadım. İlk senaryoda çıktığını fark etmeden ilkinde ölmeye devam ettim.

:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT

:: ScriptA.bat
Do Foo
EXIT
::ScriptB.bat
Do bar
EXIT

Komut dosyalarının EXIT satırlarının 11'ini kaldırdım ve tekrar denedim ve 11'in hepsi aynı komut penceresinde birer birer sırayla çalıştı.

:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar

exits'yi çıkarmayın, goto :eofonun yerine değiştirin . Bu, "geri dönecek"call
Stephan

basit bir toplu iş komutları olarak da adlandırılır sırayla çalışacağını fark edersiniz de dizinler için temel düzen, @echo off :menu some commands goto menubu kapatılana kadar sürekli bir döngü çalışacağını unutmayın. temelde ::sadece gerek yok:
CMS_95

0

Aşağıdakiler sorunumu çözdü:

start call "batch1.bat"
start call "batch2.bat"

0

Belki bunu istersin:

Toplu komut dosyalarını paralel olarak çalıştırın.

start "systemLogCollector" /min cmd /k call systemLogCollector.bat
start "uiLogCollector" /min cmd /k call uiLogCollector.bat
start "appLogCollector" /min cmd /k call appLogCollector.bat

Burada üç toplu iş dosyası ayrı komut pencerelerinde simge durumuna küçültülmüş olarak çalıştırılır. Bunların simge durumuna küçültülmesini istemiyorsanız kaldırın /min. Ayrıca, daha sonra kontrol etmeniz gerekmiyorsa, başlıklardan kurtulabilirsiniz. Yani, çıplak kemikli bir komut olacak-start cmd /k call systemLogCollector.bat


Onları feshetmek isterseniz-

taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F
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.