Unix共享目录至Windows的Batch脚本复制异常及相关问题问询
Hey there, let's work through the two problems you're facing with your batch script. I'll break down each issue, explain what's going wrong, and share a revised script that addresses both.
1. Fixing Error Capture & Silent Copy Failures
Your current script has a couple of gaps in error handling that lead to silent failures and incorrect log behavior:
- Inconsistent log paths: Some logs go to a local
PrintMateLog.logfile, while others are written to the backup directory—this makes tracking errors messy. - ErrorLevel check limitations: When the Unix share is empty, XCOPY returns ErrorLevel 1, but your script’s current structure might not reliably trigger that log entry. Plus, transient network glitches or file locks on the share can cause copy failures that don’t trigger the existing ErrorLevel checks.
- Broken delete error logging: There’s a typo in your delete command’s error log line (missing the
>>redirect), so those errors never get written.
Key Fixes:
- Unify all logs: Write every log entry to the same file in your backup directory for consistency.
- Add retry logic: Handle transient network/share issues by retrying failed copies up to 3 times.
- Improve ErrorLevel checks: Use
if errorlevel Nsyntax (which checks if the ErrorLevel is at least N) for more reliable condition matching. - Pre-validate share access: Ensure we can reach the share before attempting copies.
2. Fixing Empty Directory Checks (No More Pausing)
Your auxiliary script pauses when the directory is empty because FOR /F expects input, and when DIR returns no results, it can hang unexpectedly. Instead of a separate script, we can add a lightweight check directly in the main script to detect empty directories before trying to copy.
The Reliable Empty Directory Check:
Use DIR "%SOURCE_DIR%*.*" /A:-D | findstr . >nul—this command checks for non-directory files. If %errorlevel% equals 0, files exist; if 1, the directory is empty. No more hanging!
Revised Full Script
@echo off setlocal enabledelayedexpansion :: Define reusable constants for easy updates later set "SOURCE_DIR=X:\" set "MAIN_DEST=C:\Users\histology\Desktop\PrintMateCopy" set "BACKUP_DEST=C:\Users\histology\Desktop\PrintmateCopy2" set "LOG_FILE=%BACKUP_DEST%\PrintMateLog.log" :: Make sure backup directory exists (create if missing) if not exist "%BACKUP_DEST%" mkdir "%BACKUP_DEST%" :START :: First, check if the Unix share has any files to copy dir "%SOURCE_DIR%*.*" /A:-D | findstr . >nul if errorlevel 1 ( echo %date% : %time% : No files found in Unix share. Skipping copy cycle. >> "%LOG_FILE%" goto WAIT_FOR_NEXT_CYCLE ) :: Attempt copy with retries for transient issues set "RETRY_COUNT=0" :COPY_ATTEMPT echo %date% : %time% : Starting copy attempt %RETRY_COUNT%... >> "%LOG_FILE%" xcopy /Y /E "%SOURCE_DIR%" "%MAIN_DEST%" xcopy /Y /E "%SOURCE_DIR%" "%BACKUP_DEST%" :: Handle XCOPY error levels (check from highest to lowest severity) if errorlevel 5 ( echo %date% : %time% : Error: %errorlevel% - Disk write failure occurred. >> "%LOG_FILE%" goto WAIT_FOR_NEXT_CYCLE ) if errorlevel 4 ( echo %date% : %time% : Error: %errorlevel% - Initialization failed (insufficient memory/disk space, invalid path). >> "%LOG_FILE%" goto WAIT_FOR_NEXT_CYCLE ) if errorlevel 2 ( echo %date% : %time% : Error: %errorlevel% - Copy terminated by user (Ctrl+C). >> "%LOG_FILE%" goto WAIT_FOR_NEXT_CYCLE ) if errorlevel 1 ( echo %date% : %time% : Error: %errorlevel% - Some files failed to copy (locked or missing). >> "%LOG_FILE%" set /A RETRY_COUNT+=1 if !RETRY_COUNT! lss 3 ( echo %date% : %time% : Retrying copy in 2 seconds... >> "%LOG_FILE%" timeout /t 2 /nobreak >nul goto COPY_ATTEMPT ) else ( echo %date% : %time% : Max retries reached. Aborting copy for this cycle. >> "%LOG_FILE%" goto WAIT_FOR_NEXT_CYCLE ) ) if errorlevel 0 ( echo %date% : %time% : Copies completed successfully. Deleting source files... >> "%LOG_FILE%" del /F /Q "%SOURCE_DIR%*.*" if errorlevel 1 ( echo %date% : %time% : Warning: No files found to delete in Unix share. >> "%LOG_FILE%" ) else ( echo %date% : %time% : Source files deleted successfully. >> "%LOG_FILE%" ) ) :WAIT_FOR_NEXT_CYCLE :: Wait 3 seconds before checking the share again timeout /t 3 /nobreak >nul goto START endlocal
What’s Improved:
- Delayed expansion: Lets us update and read the retry count variable correctly inside loops.
- Centralized constants: Easy to tweak paths without hunting through the script.
- Pre-copy empty check: Skips unnecessary copy attempts when the share is empty, preventing false ErrorLevel triggers.
- Retry logic: Handles temporary network glitches or file locks with 3 retry attempts.
- Unified logging: Every log entry goes to the backup directory’s log file for easy debugging.
- Fixed delete error logging: Corrected the typo so delete failures are now logged properly.
- Consistent waiting: Uses
timeoutinstead of relying on pause, so the script runs fully automatically.
内容的提问来源于stack exchange,提问作者dancingbush

