Cách chạy nhiều tệp .BAT trong tệp .BAT


694

Tôi đang cố gắng để tôi commit-build.batthực thi các tệp .BAT khác như một phần của quy trình xây dựng của chúng tôi.

Nội dung của commit-build.bat:

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

Điều này có vẻ đơn giản, nhưng commit-build.batchỉ thực hiện mục đầu tiên trong danh sách ( msbuild.bat).

Tôi đã chạy từng tệp riêng biệt mà không gặp vấn đề gì.


4
@sean - Bạn không cần phải cài đặt gói Cygwin đầy đủ để có được các tiện ích dòng lệnh hoạt động. Chỉ cần lấy tất cả các dll cygwin ra khỏi gói đặt chúng vào một thư mục có đường dẫn, đặt tất cả các công cụ của bạn vào một thư mục có đường dẫn khác và bạn sẽ ổn.
Techie Joe

giả sử rằng mỗi tệp này chỉ là một đợt tại sao không đặt chúng vào một tệp lớn và sử dụng chức năng hết thời gian để cho phép mỗi lần bắt đầu.
CMS_95

Câu trả lời:


1199

Sử dụng:

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

Khi không sử dụng CALL, tệp bó hiện tại sẽ dừng và tệp bó được gọi bắt đầu thực thi. Đó là một hành vi kỳ dị có từ thời MS-DOS đầu tiên.


Thật kỳ lạ, tôi đã thử mà không có "cuộc gọi" trên windows 7 và tôi nhớ rằng nó đã hoạt động, nhưng trên windows xp thì nó yêu cầu lệnh này. nó có thể là?
nhà phát triển Android

7
Nếu không có cuộc gọi, theo thông số kỹ thuật ban đầu của DOS, sẽ thực hiện lệnh chuỗi và KHÔNG trả về. Một tùy chọn phổ biến trở lại trước khi "CALL" được thêm vào là mở một dấu nhắc lệnh con như "lệnh / c second.bat" vì điều đó cũng sẽ trở lại.
Brian Knoblauch

1
Tôi đã gặp sự cố trên Windows 7, vì vậy không chỉ xp
Rafiki

5
Trên Windows 10 chỉ có dòng đầu tiên được thực thi. Câu trả lời của farheen tuy nhiên có hiệu quả.
cướp

2
Làm thế nào để truyền tham số cho các tệp bó và một trong các param là đường dẫn có khoảng trắng.
Zeus

179

Tất cả các câu trả lời khác là chính xác: sử dụng cuộc gọi. Ví dụ:

 call "msbuild.bat"

Lịch sử

Trong các phiên bản DOS cổ, không thể thực hiện đệ quy các tệp bó. Sau đó, lệnh gọi được giới thiệu đã gọi shell cmd khác để thực thi tệp bó và trả lại thực thi trở lại shell cmd khi gọi xong.

Rõ ràng trong các phiên bản sau, không còn vỏ cmd nào nữa.

Trong những ngày đầu, nhiều tệp bó phụ thuộc vào thực tế là việc gọi tệp bó sẽ không trở lại tệp bó gọi. Thay đổi hành vi mà không có cú pháp bổ sung sẽ phá vỡ nhiều hệ thống như hệ thống menu bó (sử dụng tệp bó cho cấu trúc menu).

Như trong nhiều trường hợp với Microsoft, do đó khả năng tương thích ngược là lý do cho hành vi này.

Lời khuyên

Nếu các tệp bó của bạn có khoảng trắng trong tên của chúng, hãy sử dụng dấu ngoặc kép quanh tên:

call "unit tests.bat"

Nhân tiện: nếu bạn không có tất cả tên của các tệp bó, bạn cũng có thể sử dụng để thực hiện việc này (nó không đảm bảo đúng thứ tự các lệnh gọi tệp bó; nó tuân theo thứ tự của hệ thống tệp):

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

Bạn cũng có thể phản ứng với các lỗi sau khi gọi. Sử dụng:

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

để trả lại một lỗi. 0 biểu thị thực hiện đúng. Trong tệp bó cuộc gọi, bạn có thể phản ứng bằng cách sử dụng

if errorlevel neq 0 <batch command>

Sử dụng if errorlevel 1nếu bạn có Windows cũ hơn NT4 / 2000 / XP để bắt tất cả các lỗi 1 và cao hơn.

Để kiểm soát luồng của tệp bó, có goto :-(

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

Như những người khác đã chỉ ra: hãy xem các hệ thống xây dựng để thay thế các tệp bó.


đồng ý, nhưng trong trường hợp này, vòng lặp có thể xử lý các tệp theo thứ tự sai (theo bảng chữ cái?)
Dave Archer

Câu trả lời hay và rất đầy đủ. Nếu bạn bao gồm luồng điều khiển, có thể tốt để lưu ý rằng thay vì goto, bạn có thể thực hiện chương trình con bằng cách sử dụng lệnh gọi: nhãn1 và câu lệnh 'return' trong các tệp bó là goto hơi lạ: và không cần tự tạo nhãn eof, tồn tại theo mặc định).
Legolas

các errorlevelví dụ lệnh đã cho tôi một vấn đề trên Windows 10 (trong giao diện điều khiển cmd). Tôi đã sửa đổi lệnh đơn giản là được if errorlevel neq echo Houston We have a Problem!. Quá trình xử lý hàng loạt của tôi không có vấn đề gì và hoàn thành hầu hết bình thường, nhưng mỗi bước tôi sử dụng lệnh này sau khi có lệnh gọi, tôi nhận được "neq thật bất ngờ vào lúc này". Nghĩ rằng họ có thể đã thay đổi cú pháp không bằng nhau, tôi đã thử !=và cũng <>nhận được lỗi "không mong đợi tại thời điểm này" cho cú pháp mới. Tôi có thể làm gì sai?
TMWP

117

Nếu chúng ta muốn mở nhiều dấu nhắc lệnh thì chúng ta có thể sử dụng

start cmd /k

/k: là bắt buộc sẽ thực thi.

Khởi chạy nhiều dấu nhắc lệnh có thể được thực hiện như dưới đây.

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
đó là những gì chúng tôi đã tìm kiếm, vì ứng dụng đầu tiên của chúng tôi chặn bảng điều khiển, cảm ơn vì gợi ý
Michael Moeller

1
điều này sẽ chạy nhiều phiên bản lệnh và thậm chí sẽ hoạt động để chạy nhiều tệp bó có <pause>. +1 vì đây chính xác là giải pháp tôi đang tìm kiếm!
Christian Noel

5
bạn có thể vui lòng giải thích rằng những con số đó là trong câu trả lời của bạn? Mục đích của họ không rõ ràng.
Kalamalka Kid

3
Lưu ý rằng hầu hết mọi người có thể muốn sử dụng start "Window title" /wait cmd /k call something.batđể chạy mọi thứ theo thứ tự.
Andrew

3
(hoặc start "Window title" /wait cmd /c something.bat, nơi cmd /cđóng cửa sổ sau khi kết thúc)
Andrew

42

Thử:

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

28

Bạn đang gọi nhiều đợt trong nỗ lực biên dịch chương trình. Tôi chấp nhận rằng nếu xảy ra lỗi:
1) Chương trình trong lô sẽ thoát với lỗi;
2) Bạn muốn biết về nó.

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

'||' kiểm tra lỗi có giá trị cao hơn 0. Bằng cách này, tất cả các lô được gọi theo thứ tự nhưng sẽ dừng ở bất kỳ lỗi nào, để lại màn hình vì nó là để bạn thấy bất kỳ thông báo lỗi nào.


23

Nếu chúng ta có hai tập lệnh bó, aaa.bat và bbb.bat và gọi như bên dưới

call aaa.bat
call bbb.bat

Khi thực thi tập lệnh, nó sẽ gọi aaa.bat trước, đợi luồng của aaa.bat chấm dứt và gọi bbb.bat.

Nhưng nếu bạn không muốn đợi aaa.bat chấm dứt để gọi bbb.bat, hãy thử sử dụng lệnh START :

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

Thi:

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

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

20

Để gọi một .battệp trong một .battệp, sử dụng

call foo.bat

(Vâng, điều này thật ngớ ngẩn, sẽ có ý nghĩa hơn nếu bạn có thể gọi nó bằng foo.bat, giống như bạn có thể từ dấu nhắc lệnh, nhưng cách chính xác là sử dụng call.)


7

Nhìn vào tên tệp của bạn, bạn đã cân nhắc sử dụng một công cụ xây dựng như NAnt hoặc Ant (phiên bản Java). Bạn sẽ có nhiều quyền kiểm soát hơn so với các tập tin bat.


7

Nếu bạn muốn mở nhiều tệp bó cùng một lúc, bạn có thể sử dụng lệnh gọi. Tuy nhiên, lệnh gọi sẽ đóng tệp dơi hiện tại và chuyển sang tệp khác. Nếu bạn muốn mở nhiều cùng một lúc, bạn có thể muốn thử điều này:

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

Và cứ thế hoặc lặp lại bắt đầu cmd" call..." cho nhiều tệp. Điều này hoạt động cho Windows 7 , nhưng tôi không chắc chắn về các hệ thống khác.


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

Nếu điều đó không làm việc, thay thế startbằng callhoặc thử này:

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

3

Chỉ cần sử dụng calllệnh! Đây là một ví dụ:

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

3

Với trích dẫn chính xác (điều này đôi khi có thể khó khăn):

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

Arg thứ 1 - Tiêu đề (trống trong trường hợp này)
arg thứ 2 - / D chỉ định thư mục bắt đầu, có thể được sử dụng nếu muốn thư mục làm việc hiện tại (chẳng hạn như "% ~ dp0")
lệnh arg - thứ 3 sẽ khởi chạy, "cmd.exe"
4th arg - đối số để ra lệnh, với các dấu ngoặc kép tăng lên cho các đối số bên trong nó (đây là cách bạn thoát dấu ngoặc kép trong dấu ngoặc kép)


2

Chạy nhiều tập lệnh trong một tôi có cùng một vấn đề. Tôi tiếp tục khiến nó chết trong lần đầu tiên không nhận ra rằng nó đã thoát khỏi kịch bản đầu tiên.

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

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

Tôi đã xóa tất cả 11 dòng lệnh EXIT của mình và thử lại và tất cả 11 dòng chạy theo thứ tự một lần trong cùng một cửa sổ lệnh.

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

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar

không loại bỏ exits, thay thế chúng bằng goto :eofthay thế. Điều này sẽ "trở lại" vớicall
Stephan

bạn có nhận ra rằng trong một lệnh bó đơn giản sẽ chạy theo thứ tự chúng cũng được gọi là bố cục cơ bản cho các chỉ mục, @echo off :menu some commands goto menuđiều này sẽ chạy một vòng lặp liên tục cho đến khi đóng. về cơ bản, bạn không cần ::chỉ:
CMS_95

0

Sau đây đã giải quyết vấn đề của tôi:

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

0

Có thể bạn muốn điều này:

Chạy các tập lệnh bó song song-

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

Ở đây có ba tệp bó được chạy trên các cửa sổ lệnh riêng biệt ở trạng thái thu nhỏ. Nếu bạn không muốn chúng được giảm thiểu, sau đó loại bỏ /min. Ngoài ra, nếu bạn không cần kiểm soát chúng sau này, thì bạn có thể thoát khỏi các tiêu đề. Vì vậy, một lệnh xương sống sẽ là-start cmd /k call systemLogCollector.bat


Nếu bạn muốn chấm dứt chúng-

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