web-dev-qa-db-ja.com

ROBOCOPYに「適切な」終了コードを返させるには?

成功または失敗を示す終了コードでROBOCOPYに終了を依頼することは可能ですか?

私は私のTeamCityビルド構成の一部としてROBOCOPYを使用しています、そしてROBOCOPYからの終了コードを単に沈黙させるためのステップを追加しなければならないことは私にとってばかげているようです。

基本的に、私はこれを追加しました:

EXIT /B 0

実行されているスクリプトに。

しかしながら、これはもちろんROBOCOPYが返すであろう本当の問題を覆い隠します。

基本的に、ROBOCOPYが返すビットマスクではなく、SUCCESSに0、FAILUREに0以外の終了コードを付けたいと思います。

または、それができない場合、ROBOCOPYのビットマスクを同じような値に変換する簡単な一連のバッチコマンドはありますか。

ここでに従って、Robocopyには終了コードを構成する以下の終了コードビットがあります。

0×10重大なエラーです。 Robocopyはファイルをコピーしませんでした。これは使用方法エラーか、ソースディレクトリまたは宛先ディレクトリに対する不十分なアクセス権限によるエラーです。

0×08一部のファイルまたはディレクトリをコピーできませんでした(コピーエラーが発生し、再試行制限を超えました)。さらにこれらのエラーを確認してください。

0×04ファイルまたはディレクトリの不一致が検出されました。出力ログを調べてください。清掃はおそらく必要です。

0×02いくつかの余分なファイルまたはディレクトリが検出されました。出力ログを調べてください。いくつかのハウスキーピングが必要な場合があります。

0×01 1つ以上のファイルが正常にコピーされました(つまり、新しいファイルが到着しました)。

0×00エラーは発生せず、コピーも行われませんでした。コピー元とコピー先のディレクトリツリーは完全に同期されています。

戻り値が1か0の場合はEXIT /B 0、それ以外の場合はEXIT /B 1とするif/else文を追加するだけです。ファイルがコピーされた可能性があるとしても、手作業による介入が必要になるような問題があります。

46
Daniel Beck

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
101

Jenkinsから実行するには( )/Bの両方が必要です。エラーレベル1,2,3,4を無視したい場合は、

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

このページ から エラーコードのリストを使用してエラーを出力し、さまざまなコードセクションを実行するセクションをバッチファイルに追加できます。

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
13
Mokubai

私はこれを使う:

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
paradroid

上記のいくつかのポスターはビットマスクの微妙さを逃しています。特にパラドロイドは、エラーレベル3が完全に成功したコピーを示すことを見逃しています。

ビット0x01が設定されている場合は、他の障害があっても一部のファイルがコピーされていることを示します。したがって、奇数のエラーレベルは、少なくともいくつかのファイルがコピーされたことを常に示します。また、ビット0x02は、ソースに存在しないファイルが宛先にあることを単に示していることにも注意してください。これは、/ Eスイッチが使用されていて、前回のコピーが行われてからファイルがソースから削除されている場合に発生します。/MIRスイッチを使用しても、ソースのミラーリングのために宛先のファイルが削除されるため、このようなことは起こりません(ただし、これはテストしていません)。

したがって、エラーレベル1と3の両方が、エラーなしでファイルのコピーが成功したことを示します。また、エラーレベル0と2は、コピー先が最新でファイルがコピーされていないことを示します。

その価値のために、私は私の単純なバックアップのために以下を思いついた:

エラーレベル16エコーバックアップが失敗した場合 - 上記の理由を参照してください。

errorlevel 8 echoすべてがうまくいっていない場合 - バックアップが未完了&goto done

エラーレベル4の場合echoすべてがうまくいっていない - いくつかのファイルが一致していない&goto done

エラーレベル3エコーバックアップが正常に完了した後、完了した場合

エラーレベル2がエコーバックアップの場合はすでに最新の状態になっています - ファイルのコピーは行われていません。

エラーレベル1エコーバックアップが正常に完了した後、終了した場合

エラーレベル0がエコーの場合バックアップはすでに最新の状態です - ファイルはコピーされていません。

私は「余分な」ファイルについては気にしないことを選びました。

「不一致」エラーはまだ発生していないため、その原因はわかりませんが、念のために許可しています。

8
GuestJohn

私はGuest Johnに同意します - あなたが本当に結果が実際に8以上であるならば、あなたは本当にエラーを示すことを望みます。

そのため、robocopyの結果をSQLエージェントジョブでの使用に適した0(成功)または1(失敗)の結果にマッピングするには、次のようにします。

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

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
2
Paul Oliver

gitlab ciでは、その前にcmd/cを追加してください。

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

それ以外の場合、EXIT 0はその時点でCIパイプラインを閉じます。

1
Scott Pepper

Visual Studioが正常なコピーで1ではなく0を想定しているため、完成したファイルをVisual Studio 2010以降から別のフォルダーにコピーする方法の例を次に示します。

cmd /c (robocopy $(TargetDir) X:\$(TargetName) $(TargetFileName) $(TargetFileName).config *.dll *.json *.xml /xx) ^& IF %ERRORLEVEL% LEQ 1 exit 0 
0
Glenn Perkins