วิธีเรียกใช้หลายไฟล์. BAT ภายในไฟล์. BAT


695

ฉันพยายามทำให้commit-build.batไฟล์. BAT อื่น ๆ เป็นส่วนหนึ่งของกระบวนการสร้างของเรา

เนื้อหาของcommit-build.bat:

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

ดูเหมือนง่ายพอ แต่commit-build.batเรียกใช้งานรายการแรกในรายการ ( msbuild.bat)

ฉันรันแต่ละไฟล์แยกกันโดยไม่มีปัญหา


4
@sean - คุณไม่ต้องติดตั้งแพคเกจ Cygwin เพื่อรับบรรทัดคำสั่งเพื่อใช้งาน เพียงนำ cygwin dll ทั้งหมดออกจากแพ็คเกจวางไว้ในไดเรกทอรี pathed ใส่เครื่องมือทั้งหมดของคุณในไดเรกทอรี pathed อื่นและคุณก็พร้อมที่จะไป
Techie Joe

สันนิษฐานว่าไฟล์เหล่านี้แต่ละไฟล์เป็นเพียงแบตช์เหตุผลที่ไม่เพียง แต่ใส่ไว้ในไฟล์ขนาดใหญ่ไฟล์เดียวและใช้ฟังก์ชั่นการหมดเวลาเพื่ออนุญาตให้แต่ละครั้งเริ่มต้น
CMS_95

คำตอบ:


1201

ใช้:

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

เมื่อไม่ได้ใช้งาน CALL ไฟล์แบตช์ปัจจุบันจะหยุดทำงานและไฟล์แบตช์ที่เรียกว่าจะเริ่มทำงาน มันเป็นพฤติกรรมที่แปลกประหลาดย้อนหลังไปถึงช่วงต้นของ MS-DOS


แปลกฉันพยายามโดยไม่ต้อง "โทร" บน windows 7 และฉันจำได้ว่ามันทำงานได้ แต่บน windows xp ต้องใช้คำสั่งนี้ มันอาจจะเป็น?
นักพัฒนา Android

7
หากไม่มีการโทรตามข้อกำหนดของ DOS ดั้งเดิมควรทำการผูกมัดคำสั่งและไม่ส่งคืน ตัวเลือกยอดนิยมก่อนที่จะเพิ่ม "CALL" คือการเปิดพรอมต์คำสั่งชายน์เช่น "command / c second.bat" ซึ่งจะส่งคืนเช่นกัน
Brian Knoblauch

1
ฉันมีปัญหาเกี่ยวกับ entreprise ของ Windows 7 ดังนั้นจึงไม่ใช่แค่ XP
Rafiki

7
บน Windows 10 เฉพาะบรรทัดแรกเท่านั้นที่ถูกเรียกใช้งาน คำตอบโดย farheen อย่างไรก็ตามทำงาน
robro

2
วิธีส่งพารามิเตอร์ไปยังไฟล์แบตช์และหนึ่งในพารามิเตอร์คือพา ธ ที่มีช่องว่าง
ซุส

180

คำตอบอื่น ๆ ทั้งหมดถูกต้อง: ใช้การโทร ตัวอย่างเช่น:

 call "msbuild.bat"

ประวัติศาสตร์

ในรุ่น DOS โบราณมันเป็นไปไม่ได้ที่จะเรียกใช้ไฟล์แบตช์ซ้ำ จากนั้นคำสั่งการโทรถูกแนะนำที่เรียกว่าเชลล์ cmd อื่นเพื่อดำเนินการแบตช์ไฟล์และส่งกลับการดำเนินการกลับไปที่การเรียกเชลล์ cmd เมื่อเสร็จสิ้น

เห็นได้ชัดว่าในรุ่นต่อมาไม่มีเชลล์ cmd อื่นที่จำเป็นอีกต่อไป

ในวันแรก ๆ หลายชุดแบทช์ขึ้นอยู่กับความจริงที่ว่าการเรียกไฟล์แบตช์จะไม่กลับไปที่ไฟล์แบตช์การโทร การเปลี่ยนลักษณะการทำงานที่ไม่มีไวยากรณ์เพิ่มเติมจะทำให้ระบบหลาย ๆ ระบบแตกเช่นแบทช์เมนู (การใช้แบตช์ไฟล์สำหรับโครงสร้างเมนู)

ในหลาย ๆ กรณีกับ Microsoft ความเข้ากันได้แบบย้อนหลังเป็นสาเหตุของพฤติกรรมนี้

เคล็ดลับ

หากไฟล์แบตช์ของคุณมีช่องว่างในชื่อให้ใช้เครื่องหมายคำพูดล้อมรอบชื่อ:

call "unit tests.bat"

โดยวิธีการ: หากคุณไม่มีชื่อแบทช์ไฟล์ทั้งหมดคุณสามารถใช้สำหรับการทำเช่นนี้ (ไม่รับประกันลำดับที่ถูกต้องของการเรียกไฟล์แบทช์มันเป็นไปตามคำสั่งของระบบไฟล์):

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

นอกจากนี้คุณยังสามารถตอบสนองข้อผิดพลาดระดับหลังจากการโทร ใช้:

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

เพื่อคืนข้อผิดพลาดระดับ 0 หมายถึงการดำเนินการที่ถูกต้อง ในไฟล์แบตช์การเรียกคุณสามารถตอบสนองการใช้

if errorlevel neq 0 <batch command>

ใช้if errorlevel 1หากคุณมี Windows รุ่นเก่ากว่า NT4 / 2000 / XP เพื่อตรวจสอบข้อผิดพลาดระดับที่ 1 ขึ้นไป

เพื่อควบคุมการไหลของไฟล์แบทช์มี goto :-(

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

ดังที่คนอื่น ๆ ชี้ให้ดูที่ระบบการสร้างเพื่อแทนที่ไฟล์แบตช์


ที่ตกลงกันไว้ แต่ห่วงจะในกรณีนี้ประมวลผลไฟล์ในทางที่ผิดที่ (? อักษร) การสั่งซื้อ
เดฟอาร์เชอร์

คำตอบที่ดีและสมบูรณ์มาก หากคุณรวมถึงโฟลว์การควบคุมคุณควรทราบว่าแทนที่จะข้ามไปคุณสามารถทำได้รูทีนย่อยโดยใช้การโทร: label1 และคำสั่ง 'คืน' ในไฟล์แบตช์เป็น goto ที่แปลกเล็กน้อย: eof (และไม่จำเป็นต้อง ทำป้ายกำกับ eof ด้วยตัวเองซึ่งมีอยู่ตามค่าเริ่มต้น)
เลโกลัส

errorlevelตัวอย่างเช่นคำสั่งให้ฉันปัญหาบน Windows 10 (ในคอนโซล cmd) if errorlevel neq echo Houston We have a Problem!ผมปรับเปลี่ยนคำสั่งก็จะเป็น กระบวนการแบทช์ของฉันไม่มีปัญหาและส่วนใหญ่แล้วจะเสร็จสมบูรณ์ แต่ทุกขั้นตอนที่ฉันใช้คำสั่งนี้หลังจากคำสั่งเรียกฉันได้ "neq ไม่คาดคิดในเวลานี้" คิดว่าพวกเขาอาจเปลี่ยนไวยากรณ์ไม่เท่ากันฉันลอง!=แล้ว<>แต่กลับได้รับข้อผิดพลาด "ไม่ได้คาดหวังในเวลานี้" สำหรับไวยากรณ์ใหม่ ฉันจะทำอะไรผิด
TMWP

118

หากเราต้องการเปิดพรอมต์คำสั่งหลายรายการเราก็สามารถใช้

start cmd /k

/k: เป็นภาคบังคับซึ่งจะดำเนินการ

การเปิดใช้พรอมต์คำสั่งจำนวนมากสามารถทำได้ดังนี้

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
นั่นคือสิ่งที่เรากำลังค้นหาเนื่องจากแอปแรกของเราบล็อกคอนโซลขอบคุณสำหรับคำใบ้
Michael Moeller

1
สิ่งนี้จะเรียกใช้คำสั่งหลายอินสแตนซ์และยังสามารถใช้งานได้กับการทำงานหลายแบตช์ที่มี <pause> +1 เพราะนี่คือทางออกที่ฉันต้องการ!
Christian Noel

5
คุณช่วยอธิบายได้ไหมว่าตัวเลขเหล่านั้นอยู่ในคำตอบของคุณ? วัตถุประสงค์ของพวกเขามันไม่ชัดเจน
Kalamalka Kid

3
โปรดทราบว่าคนส่วนใหญ่อาจต้องการใช้start "Window title" /wait cmd /k call something.batเพื่อเรียกใช้สิ่งต่าง ๆ ตามลำดับ
แอนดรู

3
(หรือstart "Window title" /wait cmd /c something.batที่cmd /cปิดหน้าต่างเมื่อเสร็จแล้ว)
แอนดรู


28

คุณกำลังเรียกหลายแบตช์ในความพยายามรวบรวมโปรแกรม ฉันยอมรับว่าหากมีข้อผิดพลาดเกิดขึ้น:
1) โปรแกรมภายในแบทช์จะออกโดยมีระดับข้อผิดพลาด;
2) คุณต้องการรู้เกี่ยวกับมัน

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

'||' ทดสอบข้อผิดพลาดระดับสูงกว่า 0 วิธีนี้จะเรียกชุดทั้งหมดตามลำดับ แต่จะหยุดที่ข้อผิดพลาดใด ๆ ออกจากหน้าจอตามที่คุณเห็นข้อความแสดงข้อผิดพลาด


23

หากเรามีสคริปต์แบตช์สองรายการคือ aaa.bat และ bbb.bat และโทรตามด้านล่าง

call aaa.bat
call bbb.bat

เมื่อเรียกใช้งานสคริปต์สคริปต์จะเรียก aaa.bat ก่อนรอเธรดของ aaa.bat ยุติและเรียกใช้ bbb.bat

แต่ถ้าคุณไม่ต้องการรอให้ aaa.bat ยุติการโทร bbb.bat ให้ลองใช้คำสั่งSTART :

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

Exam:

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


20

หากต้องการเรียก.batไฟล์ภายใน.batไฟล์ให้ใช้

call foo.bat

(ใช่นี่มันงี่เง่ามันจะสมเหตุสมผลมากกว่าถ้าคุณสามารถเรียกมันได้foo.batเช่นเดียวกับที่คุณทำได้จากพรอมต์คำสั่ง แต่วิธีที่ถูกต้องคือการใช้call)


7

ดูที่ชื่อไฟล์ของคุณพิจารณาการใช้เครื่องมือสร้างเช่นNAntหรือ Ant (เวอร์ชัน Java) คุณจะได้รับการควบคุมมากกว่าไฟล์ค้างคาว


7

หากคุณต้องการเปิดแบตช์ไฟล์หลายไฟล์พร้อมกันคุณสามารถใช้คำสั่งโทรได้ อย่างไรก็ตามคำสั่ง call จะปิดไฟล์ bat ปัจจุบันและไปยังไฟล์อื่น หากคุณต้องการเปิดหลายรายการพร้อมกันคุณอาจลองทำสิ่งนี้:

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

และอื่น ๆ หรือเริ่มต้นซ้ำcmd" call... " สำหรับไฟล์จำนวนมาก สิ่งนี้ใช้ได้กับWindows 7แต่ฉันไม่แน่ใจเกี่ยวกับระบบอื่น


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

หากยังใช้งานไม่ได้ให้แทนที่startด้วยcallหรือลองทำสิ่งนี้:

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


3

ด้วยการอ้างอิงที่ถูกต้อง (บางครั้งอาจเป็นเรื่องยาก):

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

1 ARG - ชื่อ (ว่างในกรณีนี้)
2 ARG - / D ระบุไดเรกทอรีเริ่มต้นสามารถ ommited ถ้าต้องการ dir ทำงานปัจจุบัน (เช่น "% ~ dp0")
3 ARG - คำสั่งเพื่อเปิด "cmd.exe"
4 arg - อาร์กิวเมนต์ไปที่คำสั่งโดยเพิ่มเครื่องหมายคำพูดสองเท่าสำหรับอาร์กิวเมนต์ที่อยู่ภายใน (นี่คือวิธีที่คุณหลีกเลี่ยงอัญประกาศภายในเครื่องหมายอัญประกาศ)


2

ใช้สคริปต์หลายตัวในหนึ่งฉันมีปัญหาเดียวกัน ฉันเก็บมันไว้กับคนแรกโดยไม่รู้ตัวว่ามันออกมาจากบทแรก

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

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

ฉันลบสคริปต์ EXIT ทั้ง 11 บรรทัดออกแล้วลองอีกครั้งและทั้ง 11 คำสั่งทำงานพร้อมกันในหน้าต่างคำสั่งเดียวกัน

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

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar

อย่าลบexits แทนที่พวกเขาด้วยgoto :eofแทน นี่จะ "ย้อนกลับ" ไปยังcall
เตฟาน

คุณรู้ว่าในคำสั่งแบตช์ง่าย ๆ จะทำงานตามลำดับที่พวกเขาเรียกว่ายังเป็นรูปแบบพื้นฐานสำหรับดัชนี@echo off :menu some commands goto menuหมายเหตุนี้จะเรียกใช้วนซ้ำอย่างต่อเนื่องจนกว่าจะปิด โดยทั่วไปคุณไม่ต้องการ::เพียง:
CMS_95


0

คุณอาจต้องการสิ่งนี้:

รันแบตช์สคริปต์แบบขนาน -

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

ที่นี่สามไฟล์แบทช์จะทำงานในหน้าต่างคำสั่งแยกต่างหากในสถานะย่อ /minหากคุณไม่ต้องการให้พวกเขาลดลงแล้วลบ นอกจากนี้หากคุณไม่ต้องการควบคุมในภายหลังคุณสามารถกำจัดชื่อได้ ดังนั้นคำสั่งกระดูกเปลือยจะเป็น -start cmd /k call systemLogCollector.bat


หากคุณต้องการที่จะยุติพวกเขา -

taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.