当前有个需求,在不借助第三方工具的情况下(当然curl 其实也是三方),设备A每天运行完成的报表,传递到设备B的指定文件夹中备份。
A运行结束的时间不固定,这两台设备因为权限原因,没有办法安装第三方软件,也没有公网IP且不在一个局域网,所以考虑用一个FTP服务器做中转。
当然有更好的方案也可以同步下。
目前的其他思路:frp (本地端口映射安全性相对低),zerotier (尽量不使用三方软件)
目前未解决的问题 :如果A上传过程中触发B,那么文件可能当天没办法同步完成。(目前只有3个报表概率较低)
参考:
利用curl指令集高效操作FTP服务器_curl ftp-CSDN博客
脚本作用:
在指定的时间区间内,运行脚本时,将指定文件夹内的所有文件,上传到FTP服务器的根目录,并且删除本地文件 。 如果需要指定目录,则添加命令 (-Q "CWD Ships") Ships 为目录名
01.16 add:通过子例程的方式,实现了3次重试,对应服务端可能出现的425问题。(为预防掉线,设备A具有多出口)
原因:上传文件到Linux实例中的FTP站点时报“425 Security:Bad IP connection”错误的解决方法 - 北京,阿里云代理,阿里云代理商
ftpupdate.bat
@echo off
setlocal enabledelayedexpansion
:: 设置 FTP 服务器信息
set "FTP_SERVER=ftp://xx.xx.xx:1234"
set "USERNAME=xx"
set "PASSWORD=xx"
set "LOCAL_FOLDER=C:\Users\xx\Desktop\xx"
REM 最大重试次数
set MAX_RETRIES=3
:: 包含引号的作用是,提高准确性避免空格被纳入
:: 设置限定的小时数
set "start_hour=7"
set "end_hour=18"
:: 以下为代码
rem =============================================================================
:loop
rem 获取当前时间的小时数
for /f "tokens=1 delims=:" %%h in ("%time%") do set current_hour=%%h
rem 去除前导空格
set current_hour=!current_hour: =!
rem 检查当前时间是否在规定范围内
::LSS -小于 LEQ -小于或等于 GTR -大于 GEQ -大于或等于
if !current_hour! lss %start_hour% (
echo 时间未到,脚本退出
goto end
) else if !current_hour! geq %end_hour% (
echo 运行超时,脚本退出
goto end
)
echo start upload
:: 检查文件夹是否为空
:: pushd 将当前工作目录更改为指定的文件夹 。可以随时使用 popd 命令恢复到之前的工作目录
cd /d "%LOCAL_FOLDER%"
:: 默认认为文件夹为空
set "IS_EMPTY=1"
for %%F in (*) do (
echo.
echo.
set "IS_EMPTY=0"
echo f=%%F
set "FILE_NAME=%%F"
call :upload_file !FILE_NAME!
ping -n 2 127.0.0.1 > nul
)
if "!IS_EMPTY!" == "1" (
echo The folder is empty.
) else (
echo All files processed.
)
:end
echo Exiting the script.
::pause
exit /b
:upload_file
setlocal
set "FILE_TO_UPLOAD=%~1"
set RETRIES=0
:UPLOAD_LOOP
echo Uploading file: !FILE_TO_UPLOAD!
curl -T "!FILE_TO_UPLOAD!" -u %USERNAME%:%PASSWORD% --ftp-pasv %FTP_SERVER%
echo errorlevel=!errorlevel!
REM 检查上传是否成功
if !errorlevel! == 0 (
echo Successfully uploaded !FILE_TO_UPLOAD!, deleting local file...
del "!FILE_TO_UPLOAD!"
) else (
if !RETRIES! LEQ %MAX_RETRIES% (
set /a RETRIES+=1
echo 上传 !FILE_TO_UPLOAD! 失败,正在重试... (尝试次数: !RETRIES!)
goto UPLOAD_LOOP
)
)
exit /b
脚本作用:
在指定的时间区间内,运行脚本时,检查FTP 服务器中是否有文件,如果没有则15分钟后再次检查。如果有则下载到本地的指定目录,并删除服务器上的文件
ftpfetch.bat
@echo off
setlocal enabledelayedexpansion
:: 设置 FTP 服务器信息
set "FTP_SERVER=ftp://xx.xx.xx:1234/"
set "USERNAME=xx"
set "PASSWORD=xx"
::下载目标文件夹
set "DOWNLOAD_DIR=C:\Users\xx\Desktop\xx"
:: 包含引号的作用是,提高准确性避免空格被纳入
:: 设置限定的小时数
set "start_hour=8"
set "end_hour=18"
:: 等待的时间
set "wait_time=900"
:: 以下为代码
rem =============================================================================
:loop
rem 获取当前时间的小时数
for /f "tokens=1 delims=:" %%h in ("%time%") do set current_hour=%%h
rem 去除前导空格
set current_hour=!current_hour: =!
rem 检查当前时间是否在规定范围内
::LSS -小于 LEQ -小于或等于 GTR -大于 GEQ -大于或等于
if !current_hour! lss %start_hour% (
echo 时间未到,脚本退出
goto end
) else if !current_hour! geq %end_hour% (
echo 运行超时,脚本退出
goto end
)
rem 使用curl列出FTP目录中的文件
curl -s -H "Accept-Charset: UTF-8" --user "%USERNAME%:%PASSWORD%" "%FTP_SERVER%" > file_list.txt
rem 检查是否有文件
findstr /r /c:"[^ ]" file_list.txt > nul
if errorlevel 1 (
echo No files found, waiting for !wait_time! sed...
rem 等待
timeout /t !wait_time! > nul
goto loop
)
rem 下载所有文件
for /f "delims=" %%f in (file_list.txt) do (
rem 提取文件名
set "line=%%f"
rem 从行中提取最后一个字段(文件名)
set "filename="
::本句效率有问题!
for %%a in (!line!) do set "filename=%%a"
if defined filename (
echo Downloading !filename!...
echo "%DOWNLOAD_DIR%\!filename!"
curl --user "%USERNAME%:%PASSWORD%" "%FTP_SERVER%/!filename!" --output "%DOWNLOAD_DIR%\!filename!"
rem 删除FTP上的已下载文件
echo Deleting !filename! from FTP server...
curl --user "%USERNAME%:%PASSWORD%" -Q "DELE !filename!" "%FTP_SERVER%/!filename!"
)
)
:end
echo Exiting the script.
pause
FTP 服务器搭建使用的是爱快路由自带的FTP 服务。
因A/B 设备不在同一局域网且非固定IP。那么FTP 能做的限制就比较少。
目前做了两部分:
1. 限制来源IP范围,控制在当地运营商允许的范围中。
2. 限制FTP 服务外网访问的时间。FTP 无法定时开关,但是可以限定外部IP访问的时间,降低风险。
以前都是只贴链接不拷贝正文的,但是发现CSDN上的内容越来越多被删除或者变更为VIP,只能手动拷贝关键内容保存下了。
- 查看FTP服务器 根目录 所有文件
curl -u username:password ftp://192.168.8.210:21/
- 在FTP服务器上创建 Ships 目录
curl -u username:password ftp://192.168.8.210:21/ -Q "MKD Ships" curl -u username:password ftp://192.168.8.210:21/ -Q "MKD FromVessel" curl -u username:password ftp://192.168.8.210:21/ -Q "MKD ToVessel"
- 在FTP服务器上切换到 Ships 目录
curl -u username:password ftp://192.168.8.210:21/ -Q "CWD Ships"
- 上传文件到FTP服务器的 Ships 目录
curl -u username:password ftp://192.168.8.210:21/ -Q "CWD Ships" -T "./HldDataBridge"
- 删除FTP服务器的 Ships 目录指定的文件
curl -u username:password ftp://192.168.8.210:21/ -Q "CWD Ships" -Q "DELE HldDataBridge"
- 删除FTP服务器的 Ships 目录
curl -u username:password ftp://192.168.8.210:21/ -Q "RMD Ships"