Получение ROBOCOPY, чтобы вернуть «правильный» код выхода?

76863
Lasse Vågsæther Karlsen

Можно ли попросить ROBOCOPY выйти с кодом выхода, который указывает на успех или неудачу?

Я использую ROBOCOPY как часть моих конфигураций сборки TeamCity, и необходимость добавить шаг, чтобы просто заставить замолчать код выхода из ROBOCOPY, кажется мне глупой.

В основном я добавил это:

EXIT /B 0 

к сценарию, который выполняется.

Тем не менее, это, конечно, маскирует любые реальные проблемы, которые вернется в ROBOCOPY.

По сути, я хотел бы иметь коды выхода 0 для УСПЕХА и ненулевые для НЕИСПРАВНОСТИ вместо битовой маски, которую РОБОКОПИЯ возвращает сейчас.

Или, если у меня этого нет, есть ли простая последовательность командных команд, которая бы преобразовывала битовую маску ROBOCOPY в аналогичное значение?

111
Следует также отметить, что первые 8 кодов выхода (0-7), по-видимому, не являются ошибочными состояниями: http://stackoverflow.com/questions/16533843/psake-and-robocopy-failing longda 10 лет назад 2

10 ответов на вопрос

94
Richard Dingwall

TechNet предлагает этот однострочный конвертировать код выхода в более традиционный код выхода:

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

Или это, чтобы полностью игнорировать код выхода (т.е. не волнует, провалился ли он или преуспел):

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

Однако обе приведенные выше команды прекратят выполнение сценария после выполнения робокопии. Это проблема особенно для сборок CI. Если вы хотите использовать robocopy в этом сценарии, вам необходимо вручную установить код ошибки для нерелевантных кодов выхода. Ниже все коды ошибок ниже 8 будут переписаны без ошибок, и сценарий будет продолжен, если это возможно.

(robocopy c:\dirA c:\dirB *.*) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0 
Ницца. Нужны скобки вокруг команды robocopy, но спасли меня, используя скрипт-обертку. TheCodeKing 12 лет назад 7
Я не мог заставить этот однострочный текст работать как шаг сборки командной строки в TeamCity. Мне пришлось перенести его на отдельную строку. Я также добавил аргумент / B в команду выхода, хотя я не думаю, что это было необходимо. MikeWyatt 12 лет назад 0
Для развертывания Teamcity (и не только Teamcity) полезно набрать: `IF% ERRORLEVEL% LEQ 3 set errorlevel = 0` и в следующей строке:` if% errorlevel% neq 0 exit / b% errorlevel% `(if batch файл состоит из нескольких операций, а не только robocopy), потому что коды ОК меньше 3. http://ss64.com/nt/robocopy-exit.html DaoCacao 11 лет назад 0
В TeamCity вы должны экранировать `ERRORLEVEL` с двойным %%, например: %% ERRORLEVEL %%. В противном случае он считает это параметром сборки TeamCity. Yan Sklyarenko 11 лет назад 6
Что делает `^ &`? [ss64] (https://ss64.com/nt/syntax-esc.html#escape) говорит, что убегает, но мне кажется, что его не следует избегать? mlhDev 7 лет назад 2
44
Daniel Beck

В соответствии с здесь, Robocopy имеет следующие биты кода выхода, которые составляют код выхода:

0 × 10 Серьезная ошибка. Robocopy не копировал файлы. Это либо ошибка использования, либо ошибка из-за недостаточных прав доступа к исходным или целевым каталогам.

0 × 08 Не удалось скопировать некоторые файлы или каталоги (возникли ошибки при копировании и превышен предел повторных попыток). Проверьте эти ошибки дальше.

0 × 04 Обнаружены некоторые несоответствующие файлы или каталоги. Изучите выходной журнал. Домашнее хозяйство, вероятно, необходимо.

0 × 02 Обнаружены некоторые дополнительные файлы или каталоги. Изучите выходной журнал. Может потребоваться некоторая уборка.

0 × 01 Один или несколько файлов были успешно скопированы (то есть поступили новые файлы).

0 × 00 Ошибки не возникли, и копирование не было выполнено. Деревья каталогов источника и назначения полностью синхронизированы.

Просто добавьте операторы if / else, EXIT /B 0когда возвращаемое значение равно 1 или, возможно, 0, и EXIT /B 1иначе. Даже если файлы могли быть скопированы, что-то не так, что потребует ручного вмешательства.

18
Filippo Vitale

Запуск его от Дженкинса требует и того, ( )и другого /B. Если вы хотите игнорировать уровень ошибки 1,2,3,4:

(robocopy XXX YYY) ^& IF %ERRORLEVEL% LEQ 4 exit /B 0 
LSS 8 может быть даже лучше :) Ivan 7 лет назад 1
13
Mokubai

На этой странице вы можете добавить в свой пакетный файл раздел, который использует список кодов ошибок для вывода ошибок и запуска различных разделов кода:

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
paradroid

Я использую это:

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
GuestJohn

Some posters above have missed the subtlety of the bit mask. In particular paradroid has missed that errorlevel 3 indicates a completely successful copy.

Note that bit 0x01 if set indicates that some files have been copied even if there were other failures. So any odd numbered errorlevels always indicate that at least some files have been copied. Note also that bit 0x02 simply indicates that there are files at the destination that are not present at the source. This will happen if the /E switch is used and files have been deleted from the source since a previous copy was taken. It should not happen if the /MIR switch is used because that should delete files at the destination to mirror the source (but I haven't tested this).

So both errorlevel 1 AND 3 indicate successful copying of files with no errors. Also errorlevels 0 AND 2 indicate that the destination is up to date and no files were copied.

For what its worth I came up with the following for my simple backup:

if errorlevel 16 echo Backup failed - see reason above & goto done

if errorlevel 8 echo All is not well - backup incomplete & goto done

if errorlevel 4 echo All is not well - some files were mismatched & goto done

if errorlevel 3 echo Backup completed successfully & goto done

if errorlevel 2 echo Backup already up to date - no files copied & goto done

if errorlevel 1 echo Backup completed successfully & goto done

if errorlevel 0 echo Backup already up to date - no files copied & goto done

I chose not to bother about the 'extra' files.

I have no idea what the 'mismatched' error is because it hasn't happened yet but I allowed for it just in case.

6
ElectricLlama

Я согласен с гостем Джоном - вы действительно хотите указать ошибку, только если результат на самом деле 8 или выше.

поэтому для сопоставления результата robocopy с результатом 0 (успех) или 1 (сбой), подходящим для использования в задании агента SQL, я использую это:

 IF %ERRORLEVEL% LSS 8 EXIT /B 0 EXIT /B 1 
2
Paul Oliver

For TeamCity I'm using this and it's working quite well. Thanks to input from MikeWyatt, DaoCacao, and Yan Sklyarenko. I just needed to see a full working example to help visualize the answer.

(robocopy .\Artifacts\Fitnesse %FitDestinationFolder% /MIR) IF %%ERRORLEVEL%% LEQ 3 set errorlevel=0 IF %%ERRORLEVEL%% NEQ 0 EXIT /b %%ERRORLEVEL%% EXIT 0 
Я использую аналогичный сценарий robocopy в моем событии POST-BUILD .. поэтому зависимые библиотеки копируются в потребляющий проект приложения .exe - на которые ссылаются только через шаблон поиска инверсии управления / службы. bkwdesign 9 лет назад 1
0
Glenn Perkins

Вот пример того, как скопировать готовые файлы из 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 
0
Scott Pepper

добавьте cmd / c перед этим для gitlab ci.

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

в противном случае EXIT 0 закрывает конвейер CI в этой точке.