Azure DevOps Pipeline阶段错误处理异常:误将权限等错误判定为成功
问题:Azure DevOps Pipeline清理旧文件脚本错误处理失效
我在Azure DevOps Pipeline中配置了一个阶段,用于删除7天前的文件和文件夹。原脚本在未找到旧文件时会返回错误码1,导致阶段失败。修改脚本后希望实现:仅“无旧文件”的情况判定为成功,权限拒绝、无效路径这类实际错误则判定为失败,但目前所有错误都被视为阶段成功,比如出现权限拒绝、无效文件夹名称时,阶段依然显示完成。
原脚本
# Step 7: Delete Backups Older Than 7 Days - script: | setlocal enabledelayedexpansion set DUMP_DIR=%DUMP_DIR:"=% echo Step 7 start echo Checking DUMP_DIR: "%DUMP_DIR%" if exist %DUMP_DIR% ( echo DUMP_DIR exists: %DUMP_DIR% echo Searching for backups older than 7 days... REM 删除7天前的文件 forfiles /P "%DUMP_DIR%" /S /D -7 /C "cmd /c echo Found and deleting old file: @path & del /F /Q @path" REM 删除7天前的文件夹 forfiles /P "%DUMP_DIR%" /D -7 /C "cmd /c echo Found and deleting old folder: @path & rmdir /S /Q @path" ) else ( echo DUMP_DIR does not exist. Skipping cleanup. ) displayName: 'Delete old backups and folders'
修改后的脚本
# Step 7: Delete Backups Older Than 7 Days - script: | @echo off setlocal enabledelayedexpansion set DUMP_DIR=%DUMP_DIR:"=% echo Step 7 start echo Checking DUMP_DIR: "%DUMP_DIR%" if exist "%DUMP_DIR%" ( echo DUMP_DIR exists: %DUMP_DIR% echo Searching for backups older than 7 days... set ERROR_FOUND=0 REM 删除7天前的文件 for /f "tokens=*" %%F in ('forfiles /P "%DUMP_DIR%" /S /D -7 /C "cmd /c echo @path"') do ( echo Found and deleting old file: %%F del /F /Q "%%F" if !ERRORLEVEL! NEQ 0 ( echo Error deleting file: %%F exit 1 ) ) if !ERRORLEVEL! EQU 1 ( echo No old files found. ) REM 删除7天前的文件夹 for /f "tokens=*" %%F in ('forfiles /P "%DUMP_DIR%" /D -7 /C "cmd /c echo @path"') do ( echo Found and deleting old folder: %%F rmdir /S /Q "%%F" if !ERRORLEVEL! NEQ 0 ( echo Error deleting folder: %%F exit 1 ) ) if !ERRORLEVEL! EQU 1 ( echo No old folders found. ) ) else ( exit 1 ) displayName: 'Delete old backups and folders'
错误运行日志
Step 7 start Checking DUMP_DIR: "C:\MongoBackup" DUMP_DIR exists: C:\MongoBackup Searching for backups older than 7 days... Found and deleting old file: "C:\MongoBackup\rewrite_amd64_en-US.msi" C:\MongoBackup\rewrite_amd64_en-US.msi Přístup byl odepřen. #Access denied Found and deleting old folder: "C:\MongoBackup\rewrite_amd64_en-US.msi" Název adresáře je neplatný. #Name of folder is invalid Finishing: Delete old backups and folders
问题原因及修正方案
核心问题
for /f吃掉forfiles错误码:for /f会捕获forfiles的输出,但forfiles返回的错误码会被忽略,导致后续判断!ERRORLEVEL!无法区分“无匹配项”和“实际错误”。exit 1未正确传递退出码:在Azure DevOps的script任务中,直接使用exit 1可能会关闭cmd进程,导致Pipeline无法捕获正确的错误码,应使用exit /b 1返回脚本退出码。- 未区分文件和文件夹:删除文件夹的
forfiles会列出文件,导致用rmdir删除文件时触发无效操作错误。
修正后的脚本
# Step 7: Delete Backups Older Than 7 Days - script: | @echo off setlocal enabledelayedexpansion set "DUMP_DIR=%DUMP_DIR:"=%" echo Step 7 start echo Checking DUMP_DIR: "%DUMP_DIR%" if not exist "%DUMP_DIR%" ( echo Error: DUMP_DIR does not exist. exit /b 1 ) echo DUMP_DIR exists: %DUMP_DIR% echo Searching for backups older than 7 days... REM 处理旧文件删除 echo === Deleting old files === forfiles /P "%DUMP_DIR%" /S /D -7 /C "cmd /c if @isdir==FALSE echo @path" set FILES_ERROR=!ERRORLEVEL! if !FILES_ERROR! EQU 0 ( forfiles /P "%DUMP_DIR%" /S /D -7 /C "cmd /c if @isdir==FALSE echo Deleting old file: @path & del /F /Q @path" if !ERRORLEVEL! NEQ 0 ( echo Error occurred while deleting old files. exit /b 1 ) ) else if !FILES_ERROR! NEQ 1 ( echo Error searching for old files. exit /b 1 ) else ( echo No old files found. ) REM 处理旧文件夹删除 echo === Deleting old folders === forfiles /P "%DUMP_DIR%" /D -7 /C "cmd /c if @isdir==TRUE echo @path" set FOLDERS_ERROR=!ERRORLEVEL! if !FOLDERS_ERROR! EQU 0 ( forfiles /P "%DUMP_DIR%" /D -7 /C "cmd /c if @isdir==TRUE echo Deleting old folder: @path & rmdir /S /Q @path" if !ERRORLEVEL! NEQ 0 ( echo Error occurred while deleting old folders. exit /b 1 ) ) else if !FOLDERS_ERROR! NEQ 1 ( echo Error searching for old folders. exit /b 1 ) else ( echo No old folders found. ) echo Cleanup completed successfully. exit /b 0 displayName: 'Delete old backups and folders'
修正说明
- 区分文件/文件夹:通过
if @isdir==FALSE/TRUE过滤目标,避免用rmdir删除文件的无效操作。 - 正确处理
forfiles错误码:forfiles返回0表示找到匹配项,1表示无匹配项,其他值为实际错误。通过保存错误码并判断,仅把无匹配项视为正常,其他情况直接返回错误。 - 使用
exit /b传递退出码:exit /b会返回当前脚本的退出码,Azure DevOps Pipeline能正确捕获该码来判断阶段是否成功。 - 明确错误分支:单独处理
DUMP_DIR不存在的情况,直接返回错误码1。
内容的提问来源于stack exchange,提问作者Radek Raudenský
相关产品推荐
相关产品推荐

