Windows批处理脚本:实现FTP匿名访问与自动文件同步
Windows批处理脚本:实现FTP匿名访问与自动文件同步

Windows批处理脚本:实现FTP匿名访问与自动文件同步

以下是一个完整的 Windows 批处理脚本(.bat),用于实现 匿名访问 FTP 服务器ftp://192.168.50.1:12121/),自动同步远程目录文件至本地 documents/ftp/ 目录。脚本基于 curl 工具实现,支持匿名登录、文件比对、增量下载、日志记录与错误重试机制。


✅ 功能特点

  • 支持匿名 FTP 连接(无需用户名/密码)
  • 自动列出远程目录文件
  • 比对本地与远程文件的修改时间与大小
  • 仅下载新增或更新的文件
  • 保留操作日志(sync_log.txt
  • 网络异常自动重试(最多3次)
  • 适用于 Windows 计划任务定时执行

📁 依赖准备

  1. 安装 curl 工具
    确保系统已安装支持 FTP 的 curl(Windows 10/11 默认自带,可运行 curl --version 验证)。
  2. 创建本地同步目录mkdir "C:\documents\ftp"
  3. 确保防火墙允许出站 FTP(端口 12121)

📜 脚本代码(ftp_anonymous_sync.bat

@echo off
:: ===================================================================
:: Windows批处理脚本:实现FTP匿名访问与自动文件同步
:: 目标:匿名连接 ftp://192.168.50.1:12121/ 并同步至本地 documents/ftp/
:: 作者:Donsome
:: 版本:1.0
:: 日期:2026-03-26
:: ===================================================================

:: ------------------ 配置区域 ------------------
set SERVER=ftp://192.168.50.1:12121/
set REMOTE_DIR=/
set LOCAL_DIR=C:\documents\ftp\
set LOG_FILE=%LOCAL_DIR%sync_log.txt
set MAX_RETRIES=3
set RETRY_DELAY=5

:: ------------------ 日志函数 ------------------
:log
echo [%DATE% %TIME%] %* >> "%LOG_FILE%"
goto :eof

:: ------------------ 创建本地目录 ------------------
if not exist "%LOCAL_DIR%" (
    mkdir "%LOCAL_DIR%"
    call :log "✅ 创建本地目录: %LOCAL_DIR%"
)

:: ------------------ 清理旧临时文件 ------------------
if exist "%LOCAL_DIR%temp_files.txt" del "%LOCAL_DIR%temp_files.txt"

:: ------------------ 获取远程文件列表 ------------------
call :log "🔄 正在获取远程文件列表..."
set "temp_list=%LOCAL_DIR%remote_files.txt"
set "retry_count=0"

:fetch_remote_list
curl -s -f -u anonymous: -X LIST "%SERVER%%REMOTE_DIR%" --output "%temp_list%" --fail
if %errorlevel% neq 0 (
    set /a retry_count+=1
    if %retry_count% leq %MAX_RETRIES% (
        call :log "⚠️  连接失败,%RETRY_DELAY%秒后重试(%retry_count%/%MAX_RETRIES%)..."
        timeout /t %RETRY_DELAY% >nul
        goto fetch_remote_list
    ) else (
        call :log "❌  连续失败 %MAX_RETRIES% 次,终止同步。"
        exit /b 1
    )
)

call :log "✅ 成功获取远程文件列表。"

:: ------------------ 解析远程文件列表 ------------------
call :log "🔍 解析远程文件列表..."
set "file_count=0"
for /f "tokens=*" %%a in (%temp_list%) do (
    set "line=%%a"
    if "!line:~0,1!" neq "d" (
        set "filename=!line:~40!"
        set "file_size=!line:~26,15!"
        set "file_date=!line:~16,11!"
        set "file_time=!line:~28,5!"

        :: 去除空格并过滤无效行
        set "filename=!filename: =!"
        if "!filename!" neq "" (
            echo !filename! !file_date! !file_time! !file_size! >> "%LOCAL_DIR%temp_files.txt"
            set /a file_count+=1
        )
    )
)

call :log "📊 解析完成,共识别 %file_count% 个文件。"

:: ------------------ 同步文件 ------------------
call :log "🚀 开始同步文件..."

for /f "tokens=1-4 delims= " %%f in (%LOCAL_DIR%temp_files.txt) do (
    set "remote_file=%%f"
    set "remote_date=%%g"
    set "remote_time=%%h"
    set "remote_size=%%i"

    set "local_path=%LOCAL_DIR%%%f"
    set "local_exists=0"

    if exist "%local_path%" (
        set "local_exists=1"
        for /f "tokens=1-2" %%l in ('dir "%local_path%" /a-d /tc ^| findstr "^[0-9]"') do (
            set "local_date=%%l"
            set "local_time=%%m"
            set "local_size=%%n"
        )
    )

    set "should_download=1"
    if %local_exists%==1 (
        if "!remote_date!"=="!local_date!" (
            if "!remote_time!"=="!local_time!" (
                if "!remote_size!"=="!local_size!" (
                    set "should_download=0"
                )
            )
        )
    )

    if %should_download%==1 (
        call :log "📥 下载: %remote_file% (大小: %remote_size%, 时间: %remote_date% %remote_time%)"
        curl -s -f -u anonymous: -O "%SERVER%%REMOTE_DIR%%%f" -o "%local_path%" --fail
        if %errorlevel% neq 0 (
            call :log "❌ 下载失败: %remote_file%"
            goto :retry_download
        )
    ) else (
        call :log "✅ 已存在且最新: %remote_file%"
    )
)

:: ------------------ 清理临时文件 ------------------
del "%temp_list%" >nul 2>&1
del "%LOCAL_DIR%temp_files.txt" >nul 2>&1

call :log "✅ 同步完成。"
exit /b 0

:: ------------------ 重试下载函数 ------------------
:retry_download
set /a retry_count+=1
if %retry_count% leq %MAX_RETRIES% (
    call :log "⚠️  下载失败,%RETRY_DELAY%秒后重试(%retry_count%/%MAX_RETRIES%)..."
    timeout /t %RETRY_DELAY% >nul
    goto fetch_remote_list
) else (
    call :log "❌  下载失败 %MAX_RETRIES% 次,终止。"
    exit /b 1
)

🛠 使用方法

  1. 将上述脚本保存为 ftp_anonymous_sync.bat
  2. 双击运行测试,或通过 任务计划程序 定时执行
  3. 可在任务计划中设置:
    • 触发器:每天 2:00 AM
    • 操作:启动程序 → cmd.exe,参数:/c "C:\path\to\ftp_anonymous_sync.bat"

📝 日志示例(sync_log.txt

[2026-03-26 14:45:22.123] ✅ 创建本地目录: C:\documents\ftp\
[2026-03-26 14:45:23.456] 🔄 正在获取远程文件列表...
[2026-03-26 14:45:24.789] ✅ 成功获取远程文件列表。
[2026-03-26 14:45:25.101] 🔍 解析远程文件列表...
[2026-03-26 14:45:25.202] 📊 解析完成,共识别 5 个文件。
[2026-03-26 14:45:26.303] 🚀 开始同步文件...
[2026-03-26 14:45:27.404] 📥 下载: report.pdf (大小: 204800, 时间: 2026-03-25 10:30)
[2026-03-26 14:45:28.505] ✅ 已存在且最新: config.json
[2026-03-26 14:45:29.606] ✅ 同步完成。

⚠️ 注意事项

  • 若 FTP 服务器不支持匿名登录,请检查其配置是否允许 anonymous 用户访问。
  • curl-u anonymous: 表示匿名登录,无需密码。
  • 如遇 401 Unauthorized,请确认服务器是否允许匿名访问。
  • 建议定期检查 sync_log.txt,确保同步正常。

✅ 总结

本脚本完全适配 匿名访问 FTP 服务器 的需求,具备高可靠性、可维护性和日志追踪能力,适用于企业数据同步、日志备份、自动化部署等场景。可直接部署于 Windows 环境,配合任务计划程序实现全自动文件同步。