รับ ROBOCOPY เพื่อส่งคืนรหัสทางออก“ เหมาะสม” หรือไม่


121

เป็นไปได้หรือไม่ที่จะขอให้ ROBOCOPY ออกด้วยรหัสทางออกซึ่งบ่งชี้ความสำเร็จหรือความล้มเหลว?

ฉันกำลังใช้ ROBOCOPY เป็นส่วนหนึ่งของการกำหนดค่าการสร้าง TeamCity ของฉันและต้องเพิ่มขั้นตอนเพียงแค่ปิดเสียงรหัสทางออกจาก ROBOCOPY ให้ดูโง่ไปหน่อย

โดยทั่วไปฉันได้เพิ่มสิ่งนี้:

EXIT /B 0

ไปยังสคริปต์ที่กำลังทำงานอยู่

อย่างไรก็ตามหลักสูตรนี้จะปกปิดปัญหาที่แท้จริงของ ROBOCOPY ที่จะกลับมา

โดยทั่วไปฉันต้องการให้รหัสออกเป็น 0 สำหรับความสำเร็จและไม่เป็นศูนย์สำหรับ FAILURE แทนที่จะเป็นบิตมาสก์ที่ ROBOCOPY ส่งคืนในขณะนี้

หรือถ้าฉันไม่สามารถทำได้มีลำดับของคำสั่งแบทช์อย่างง่าย ๆ ที่จะแปล bit-mask ของ ROBOCOPY ให้เป็นค่าที่คล้ายกันหรือไม่?


2
มันก็ควรจะตั้งข้อสังเกตว่าคนแรกที่ 8 รหัสออก (0-7) จะเห็นได้ชัดว่าไม่ผิดพลาดฯ : stackoverflow.com/questions/16533843/psake-and-robocopy-failing
Longda

คำตอบ:


47

ตามที่นี่ Robocopy มีบิตรหัสทางออกต่อไปนี้ซึ่งประกอบเป็นรหัสการออก:

0 × 10 ข้อผิดพลาดที่ร้ายแรง Robocopy ไม่ได้คัดลอกไฟล์ใด ๆ นี่เป็นข้อผิดพลาดในการใช้งานหรือข้อผิดพลาดเนื่องจากสิทธิ์การเข้าถึงไม่เพียงพอในไดเรกทอรีต้นทางหรือปลายทาง

0 × 08 ไม่สามารถคัดลอกไฟล์หรือไดเรกทอรีบางไฟล์ได้ (เกิดข้อผิดพลาดในการคัดลอกและเกินขีด จำกัด การลองซ้ำ) ตรวจสอบข้อผิดพลาดเหล่านี้เพิ่มเติม

0 × 04 ตรวจพบไฟล์หรือไดเรกทอรีที่ไม่ตรงกันบางตัว ตรวจสอบบันทึกผลลัพธ์ อาจจำเป็นต้องทำความสะอาด

0 × 02 ตรวจพบไฟล์หรือไดเรกทอรีบางส่วน ตรวจสอบบันทึกผลลัพธ์ อาจจำเป็นต้องมีการทำความสะอาด

0 × 01 หนึ่งไฟล์ขึ้นไปถูกคัดลอกสำเร็จ (นั่นคือไฟล์ใหม่มาถึงแล้ว)

0 × 00 ไม่มีข้อผิดพลาดเกิดขึ้นและไม่มีการคัดลอก แผนผังไดเร็กทอรีต้นทางและปลายทางถูกซิงโครไนซ์อย่างสมบูรณ์

เพียงแค่เพิ่มคำสั่ง if / else ว่าEXIT /B 0เมื่อค่าส่งคืนเป็น 1 หรืออาจเป็น 0 และEXIT /B 1อย่างอื่น แม้ว่าไฟล์อาจได้รับการคัดลอกมีบางอย่างผิดปกติที่จะต้องมีการแทรกแซงด้วยตนเอง


108

TechNet แนะนำซับในตัวนี้เพื่อแปลงรหัสการออกเป็นรหัสการออกแบบดั้งเดิมมากขึ้น:

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LEQ 1 exit 0

หรือนี่เพื่อละเว้นรหัสออกอย่างสมบูรณ์ (เช่นไม่สนใจว่ามันล้มเหลวหรือสำเร็จ):

(robocopy c:\dirA c:\dirB *.*) ^& exit 0

อย่างไรก็ตามคำสั่งทั้งสองข้างต้นจะยุติสคริปต์หลังจาก robocopy ได้ดำเนินการแล้ว นี่เป็นปัญหาโดยเฉพาะอย่างยิ่งสำหรับ CI builds หากคุณต้องการใช้ robocopy ในสถานการณ์นี้คุณต้องตั้งรหัสข้อผิดพลาดด้วยตนเองสำหรับรหัสออกที่ไม่เกี่ยวข้อง ด้านล่างรหัสข้อผิดพลาดด้านล่าง 8 ทั้งหมดจะถูกเขียนใหม่เป็นไม่มีข้อผิดพลาดเลยและสคริปต์จะยังคงดำเนินต่อไปถ้าเป็นไปได้

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0

8
ดี ต้องการวงเล็บปิดคำสั่ง robocopy แต่ช่วยฉันด้วยสคริปต์ wrapper
TheCodeKing

ฉันไม่สามารถทำให้สายการบินเดียวทำงานเป็นขั้นตอนการสร้าง Command Line ใน TeamCity ฉันต้องย้ายมันเป็นเส้นแยก ฉันยังเพิ่มอาร์กิวเมนต์ / B ลงในคำสั่ง exit แม้ว่าฉันไม่คิดว่าจำเป็น
MikeWyatt

สำหรับการปรับใช้ Teamcity (และไม่เพียง แต่ Teamcity) มันมีประโยชน์ในการพิมพ์: IF %ERRORLEVEL% LEQ 3 set errorlevel=0และในบรรทัดถัดไป: if %errorlevel% neq 0 exit /b %errorlevel%(หากไฟล์แบตช์ประกอบด้วยการดำเนินการหลายอย่างไม่เพียง แต่ robocopy) เพราะรหัส OK น้อยกว่า 3 ss64.com/nt/robocopy -exit.html
DaoCacao

6
ใน TeamCity คุณควรหลีกเลี่ยงERRORLEVELด้วย double %% เช่นนี้: %% ERRORLEVEL %% มิฉะนั้นจะถือว่าเป็นพารามิเตอร์การสร้าง TeamCity
Yan Sklyarenko

2
อะไร^&ทำอย่างไร ss64พูดว่าการหลบหนี แต่ดูเหมือนว่าสำหรับฉันแล้วมันไม่น่าจะรอดไปได้?
mlhDev

19

เล่นได้จากเจนกินส์ต้องการทั้งสองและ( ) /Bหากคุณต้องการละเว้นข้อผิดพลาดระดับ 1,2,3,4:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0

2
LSS 8 อาจจะดียิ่งขึ้น :)
อีวาน

13

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

if %ERRORLEVEL% EQU 16 echo ***FATAL ERROR*** & goto end
if %ERRORLEVEL% EQU 15 echo OKCOPY + FAIL + MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 14 echo FAIL + MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 13 echo OKCOPY + FAIL + MISMATCHES & goto end
if %ERRORLEVEL% EQU 12 echo FAIL + MISMATCHES& goto end
if %ERRORLEVEL% EQU 11 echo OKCOPY + FAIL + XTRA & goto end
if %ERRORLEVEL% EQU 10 echo FAIL + XTRA & goto end
if %ERRORLEVEL% EQU 9 echo OKCOPY + FAIL & goto end
if %ERRORLEVEL% EQU 8 echo FAIL & goto end
if %ERRORLEVEL% EQU 7 echo OKCOPY + MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 6 echo MISMATCHES + XTRA & goto end
if %ERRORLEVEL% EQU 5 echo OKCOPY + MISMATCHES & goto end
if %ERRORLEVEL% EQU 4 echo MISMATCHES & goto end
if %ERRORLEVEL% EQU 3 echo OKCOPY + XTRA & goto end
if %ERRORLEVEL% EQU 2 echo XTRA & goto end
if %ERRORLEVEL% EQU 1 echo OKCOPY & goto end
if %ERRORLEVEL% EQU 0 echo No Change & goto end


:END
REM END OF BATCH FILE

8

ฉันใช้สิ่งนี้:

robocopy .....
call :REPORT_ERRORLEVEL
goto :EOF

:REPORT_ERRORLEVEL
echo.
if ERRORLEVEL 16 echo ***FATAL ERROR*** & goto :EOF
if ERRORLEVEL 8 echo **FAILED COPIES** & goto :EOF
if ERRORLEVEL 4 echo *MISMATCHES* & goto :EOF
if ERRORLEVEL 2 echo EXTRA FILES & goto :EOF
if ERRORLEVEL 1 echo Copy successful & goto :EOF
if ERRORLEVEL 0 echo –no change– & goto :EOF

8

ผู้โพสต์บางคนด้านบนพลาดบิตของหน้ากากเล็กน้อย โดยเฉพาะอย่างยิ่งพาราดรอยด์ที่พลาด errorlevel 3 หมายถึงสำเนาที่ประสบความสำเร็จอย่างสมบูรณ์

โปรดทราบว่าบิต 0x01 หากตั้งค่าบ่งชี้ว่ามีการคัดลอกไฟล์บางไฟล์แม้ว่าจะมีความล้มเหลวอื่น ๆ ดังนั้นระดับข้อผิดพลาดที่เป็นเลขคี่จะแสดงว่ามีการคัดลอกไฟล์อย่างน้อยบางไฟล์ โปรดทราบว่าบิต 0x02 เพียงระบุว่ามีไฟล์ที่ปลายทางที่ไม่ปรากฏที่ต้นทาง สิ่งนี้จะเกิดขึ้นหากมีการใช้สวิตช์ / E และไฟล์ถูกลบออกจากแหล่งตั้งแต่คัดลอกก่อนหน้านี้ ไม่ควรเกิดขึ้นหากใช้สวิตช์ / MIR เนื่องจากควรลบไฟล์ที่ปลายทางเพื่อทำมิเรอร์แหล่งที่มา (แต่ฉันยังไม่ได้ทดสอบสิ่งนี้)

ดังนั้นทั้งข้อผิดพลาดระดับ 1 และ 3 บ่งชี้ว่าการคัดลอกไฟล์สำเร็จโดยไม่มีข้อผิดพลาด ข้อผิดพลาดระดับ 0 และ 2 บ่งชี้ว่าปลายทางเป็นปัจจุบันและไม่มีการคัดลอกไฟล์

สำหรับสิ่งที่คุ้มค่าฉันมาพร้อมกับสิ่งต่อไปนี้สำหรับการสำรองข้อมูลอย่างง่ายของฉัน:

ถ้า errorlevel 16 echo Backup ล้มเหลว - ดูเหตุผลข้างต้น & กลับไปทำแล้ว

ถ้า errorlevel 8 echo All ไม่ดี - การสำรองข้อมูลไม่สมบูรณ์ & กลับไปแล้ว

ถ้า errorlevel 4 echo All ไม่ดี - บางไฟล์ไม่ตรงกัน & กลับไปแล้ว

ถ้า errorlevel 3 echo Backup เสร็จสมบูรณ์ & กลับไปทำสำเร็จ

ถ้า errorlevel 2 echo Backup เป็นรุ่นล่าสุดแล้ว - ไม่มีไฟล์ที่คัดลอก & ไปแล้ว

ถ้า errorlevel 1 echo Backup เสร็จสมบูรณ์ & กลับไปทำสำเร็จ

หาก errorlevel 0 echo Backup เป็นรุ่นล่าสุดแล้ว - ไม่มีไฟล์ที่คัดลอก & ไปแล้ว

ฉันเลือกที่จะไม่ใส่ใจกับไฟล์ 'พิเศษ'

ฉันไม่รู้ว่าข้อผิดพลาด 'ไม่ตรงกัน' นั้นเป็นอย่างไรเพราะมันยังไม่เกิดขึ้น แต่ฉันอนุญาตในกรณีนี้


6

ฉันเห็นด้วยกับแขกจอห์น - คุณต้องการระบุข้อผิดพลาดหากผลลัพธ์นั้นเป็น 8 หรือสูงกว่าเท่านั้น

ดังนั้นในการแมปผล robocopy กับผลลัพธ์ 0 (สำเร็จ) หรือ 1 (ล้มเหลว) เหมาะสำหรับใช้ในงาน SQL Agent ฉันใช้สิ่งนี้:

  IF %ERRORLEVEL% LSS 8 EXIT /B 0
  EXIT /B 1

2

สำหรับ TeamCity ฉันใช้สิ่งนี้และมันใช้งานได้ดี ขอขอบคุณข้อมูลจาก MikeWyatt, DaoCacao และ Yan Sklyarenko ฉันแค่ต้องการเห็นตัวอย่างการทำงานเต็มรูปแบบเพื่อช่วยให้เห็นภาพคำตอบ

(robocopy  .\Artifacts\Fitnesse %FitDestinationFolder% /MIR)
IF %%ERRORLEVEL%% LEQ 3 set errorlevel=0
IF %%ERRORLEVEL%% NEQ 0 EXIT /b %%ERRORLEVEL%%
EXIT 0

1
ฉันกำลังใช้สคริปต์ robocopy ที่คล้ายกันในเหตุการณ์ POST-BUILD ของฉัน .. ดังนั้นไลบรารีที่ขึ้นต่อกันจะถูกคัดลอกไปยังโครงการแอปพลิเคชัน. exe ที่ใช้งานอยู่ - ซึ่งอ้างอิงผ่านรูปแบบผกผันของการควบคุม / เซอร์วิสตำแหน่ง
bkwdesign

1

เพิ่ม cmd / c ก่อนหน้าสำหรับ gitlab ci

cmd /c (robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LEQ 1 exit 0

มิฉะนั้น EXIT 0 จะปิด CI ไปป์ไลน์ ณ จุดนั้น


0

ตัวอย่างที่นี่เกี่ยวกับวิธีการคัดลอกไฟล์สำเร็จรูปจาก Visual Studio 2010+ ไปยังโฟลเดอร์อื่นเนื่องจาก Visual Studio คาดว่าจะเป็น 0 ไม่ใช่ 1 สำหรับการคัดลอกที่ดี

cmd /c (robocopy $(TargetDir) X:\$(TargetName) $(TargetFileName) $(TargetFileName).config *.dll *.json *.xml /xx) ^& IF %ERRORLEVEL% LEQ 1 exit 0 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.