curl操作ftp文件

vps.dance 2023-02-10 1232℃

通过shell命令行对ftp文件管理的工具有很多, 但是都要额外安装, 其实用curl就可满足大部分场景.
整理了一些常用的ftp操作(上传/下载/删除), 并且写了删除旧文件的例子.

curl获取ftp目录文件列表

# 常规文件列表
curl -s -u username:password ftp://ftp.example.com/test/
# 带文件时间戳的列表
curl -s -u username:password ftp://ftp.example.com/test/ -X MLSD

curl上传文件到ftp目录

# -T 指定要上传的文件
# --ftp-create-dirs 表示自动创建不存在的目录
curl -u username:password ftp://ftp.example.com/test/ --ftp-create-dirs -T ./1.txt
# 也可以指定上传后的文件名
curl -u username:password ftp://ftp.example.com/test/2.txt --ftp-create-dirs -T ./1.txt

curl下载ftp的文件

# -o 指定保存的文件名
curl -u username:password ftp://ftp.example.com/test/1.txt -o ./my.file
# ps: 如果ftp目录绑定了域名, 也可通过http方式下载

curl删除ftp的文件

# DELE 后面为文件路径
curl -u username:password ftp://ftp.example.com -Q "DELE /test/1.txt"

curl移动或重命名ftp的文件

# RNFR 表示原文件, RNTO表示 目标文件
curl -u username:password ftp://ftp.example.com -Q "RNFR /test/1.txt" -Q "RNTO /1.txt.done"

curl 创建或删除目录

# 创建目录(上级目录要存在)
curl -u username:password ftp://ftp.example.com/test/ -Q "MKD /test/aa"
# 删除文件夹(要为空文件夹)
curl -u username:password ftp://ftp.example.com/test/ -Q "RMD /test/aa"

进阶 删除旧文件, 保留最新n个文件

例子, 按文件时间排序, 仅保留5个最新的文件, 其余的全部删除. 可另存为delete_old_ftp_files.sh测试.

#!/bin/bash

# FTP Server Information
FTP_HOST=""
FTP_USER=""
FTP_PASS=""
# folder path must end with "/"
FTP_DIR="/tmp/"

# Number of files to keep
NUM_FILES_TO_KEEP=5

# Get a list of files in the FTP server
files=$(curl -s -u $FTP_USER:$FTP_PASS ftp://$FTP_HOST${FTP_DIR} -X MLSD | grep 'type=file')
# Sort by modify time
files=$(echo "$files" | cut -d';' -f3,8 | sort -k1)
# echo -e "${files}"
# get file name
files=$(echo "$files" | cut -d';' -f2)

# Find the number of files
num_files=$(echo "$files" | wc -l)

# Delete all files except the newest NUM_FILES_TO_KEEP
if [ $num_files -gt $NUM_FILES_TO_KEEP ]; then
  files_to_delete=$(echo "$files" | head -n $((num_files - NUM_FILES_TO_KEEP)))
  for file in $files_to_delete; do
    # echo "DELETE $file"
    curl -u $FTP_USER:$FTP_PASS -Q "DELE ${FTP_DIR}/$file" ftp://$FTP_HOST${FTP_DIR} > /dev/null 2>&1
  done
fi

进阶 删除某个时间之前的文件

例子, 删除 5天前 或 2小时之前 的旧文件.

#!/bin/bash

# FTP Server Information
FTP_HOST=""
FTP_USER=""
FTP_PASS=""
# folder path must end with "/"
FTP_DIR="/tmp/"

# compare_date=$(date -d '-5 days' +'%s') # 5天前
compare_date=$(date -d '-2 hours' +'%s') # 2小时前

# Get a list of files in the FTP server
files=$(curl -s -u $FTP_USER:$FTP_PASS ftp://$FTP_HOST${FTP_DIR} -X MLSD | grep 'type=file' | cut -d';' -f3,8)
# echo -e "${files}"

# echo $(date +'%Y-%m-%d %H:%M:%S') $(date +'%s')
while IFS= read -r line
do
  # echo "$line"
  file=$(echo "$line" | cut -d';' -f2)
  dt=$(echo "$line" | cut -d';' -f1 | cut -d'=' -f2)
  # -00:00 指定ftp返回时间的时区
  datetime="${dt:0:8} ${dt:8:2}:${dt:10:2}:${dt:12:2} -00:00"
  timestamp=$(date -d "$datetime" +'%s')
  # echo $file, $dt, $(TZ=Asia/Shanghai date -d "@$timestamp" +'%FT%T %z'), $(TZ=Asia/Shanghai date -d "@$compare_date" +'%FT%T %z')
  if [[ "$timestamp" < "$compare_date" ]]; then
    # echo "DELETE $file"
    curl -u $FTP_USER:$FTP_PASS -Q "DELE ${FTP_DIR}/$file" ftp://$FTP_HOST${FTP_DIR} > /dev/null 2>&1
  fi
done < <(printf '%s\n' "$files")

总结

如果是sftp协议, 那么ftp的URL使用 sftp://ftp.example.com

标签: curl, ftp

非特殊说明, 所有文章均为原创.