目 录CONTENT

文章目录

Linux实时FTP文件下载方案总结

ZERO
2025-12-09 / 0 评论 / 0 点赞 / 4 阅读 / 0 字

要实现 Linux 下使用 inotifywait 结合 FTP 实时下载文件,需要理解一个关键点:inotifywait 只能监控本地文件系统的变化,无法直接监控远程 FTP 服务器的变化。

因此,这里有两种实现方案:

方案一:使用 FTP 挂载 + inotifywait(推荐)

将 FTP 服务器挂载到本地文件系统,然后监控这个挂载目录。

1. 安装必要工具

# Debian/Ubuntu
sudo apt-get install curlftpfs inotify-tools lftp

# RHEL/CentOS
sudo yum install fuse curlftpfs inotify-tools lftp

2. 创建挂载点和脚本

#!/bin/bash
# ftp_monitor.sh

# 配置参数
FTP_SERVER="ftp.example.com"
FTP_USER="username"
FTP_PASS="password"
REMOTE_DIR="/remote/path"
LOCAL_DIR="/local/download/path"
MOUNT_POINT="/mnt/ftp_mount"

# 创建目录
mkdir -p "$MOUNT_POINT" "$LOCAL_DIR"

# 挂载 FTP(使用 curlftpfs)
curlftpfs "$FTP_USER:$FTP_PASS@$FTP_SERVER" "$MOUNT_POINT" -o allow_other

# 监控 FTP 挂载目录
inotifywait -m -r -e create,moved_to --format '%w%f' "$MOUNT_POINT/$REMOTE_DIR" |
while read file
do
    echo "检测到新文件: $file"
    
    # 提取文件名
    filename=$(basename "$file")
    
    # 使用 lftp 下载文件(比 cp 更稳定)
    lftp -u "$FTP_USER,$FTP_PASS" "$FTP_SERVER" <<EOF
        cd "$REMOTE_DIR"
        get "$filename" -o "$LOCAL_DIR/$filename"
        bye
EOF
    
    echo "文件已下载: $LOCAL_DIR/$filename"
done

方案二:定期检查 + FTP 同步

如果没有挂载 FTP 的权限,可以使用定期检查的方式:

#!/bin/bash
# ftp_sync.sh

# 配置参数
FTP_SERVER="ftp.example.com"
FTP_USER="username"
FTP_PASS="password"
REMOTE_DIR="/remote/path"
LOCAL_DIR="/local/download/path"
SYNC_INTERVAL=5  # 检查间隔(秒)

# 创建本地目录
mkdir -p "$LOCAL_DIR"

# 获取初始文件列表
lftp -u "$FTP_USER,$FTP_PASS" "$FTP_SERVER" <<EOF > /tmp/ftp_files.old
    cd "$REMOTE_DIR"
    ls
    bye
EOF

while true; do
    sleep $SYNC_INTERVAL
    
    # 获取当前文件列表
    lftp -u "$FTP_USER,$FTP_PASS" "$FTP_SERVER" <<EOF > /tmp/ftp_files.new
        cd "$REMOTE_DIR"
        ls
        bye
EOF
    
    # 比较文件差异
    new_files=$(comm -13 <(sort /tmp/ftp_files.old) <(sort /tmp/ftp_files.new) | grep -v '^\.')
    
    if [ ! -z "$new_files" ]; then
        echo "发现新文件: $new_files"
        
        # 下载新文件
        for file in $new_files; do
            lftp -u "$FTP_USER,$FTP_PASS" "$FTP_SERVER" <<EOF
                cd "$REMOTE_DIR"
                get "$file" -o "$LOCAL_DIR/$file"
                bye
EOF
            echo "已下载: $file"
        done
        
        # 更新文件列表
        mv /tmp/ftp_files.new /tmp/ftp_files.old
    fi
done

方案三:使用 inotifywait 监控本地,自动上传到 FTP(反向)

如果你需要监控本地目录,然后自动上传到 FTP:

#!/bin/bash
# upload_to_ftp.sh

# 配置参数
LOCAL_WATCH_DIR="/local/watch/path"
FTP_SERVER="ftp.example.com"
FTP_USER="username"
FTP_PASS="password"
REMOTE_DIR="/remote/upload/path"

# 监控本地目录
inotifywait -m -r -e close_write,moved_to --format '%w%f' "$LOCAL_WATCH_DIR" |
while read file
do
    echo "检测到新文件: $file"
    
    # 提取文件名
    filename=$(basename "$file")
    
    # 上传到 FTP
    lftp -u "$FTP_USER,$FTP_PASS" "$FTP_SERVER" <<EOF
        cd "$REMOTE_DIR"
        put "$file"
        bye
EOF
    
    echo "文件已上传: $filename"
done

安装和使用步骤

  1. 安装依赖
sudo apt-get install inotify-tools lftp curlftpfs
  1. 创建脚本
nano ftp_monitor.sh
# 粘贴上述脚本内容
chmod +x ftp_monitor.sh
  1. 配置 FTP 凭据
    编辑脚本,设置正确的 FTP 服务器信息。

  2. 运行脚本

# 方案一
./ftp_monitor.sh

# 或作为服务运行
nohup ./ftp_monitor.sh > /var/log/ftp_monitor.log 2>&1 &
  1. 配置 systemd 服务(可选):
sudo nano /etc/systemd/system/ftp-monitor.service
[Unit]
Description=FTP Monitor Service
After=network.target

[Service]
Type=simple
User=yourusername
ExecStart=/path/to/ftp_monitor.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

注意事项

  1. 安全性:不要在脚本中硬编码密码,可以考虑使用:

    • 密码文件:~/.netrc
    • 环境变量
    • 配置文件
  2. 错误处理:添加适当的错误处理:

# 在关键操作后检查返回值
if [ $? -ne 0 ]; then
    echo "错误: 下载失败"
    # 重试或记录日志
fi
  1. 日志记录:建议添加日志记录:
log_file="/var/log/ftp_sync.log"
echo "$(date): 开始同步" >> "$log_file"
  1. 性能考虑
    • 对于大量文件,使用 lftp mirror 命令更高效
    • 调整 inotifywait 的事件类型避免重复触发

选择哪种方案取决于你的具体需求。方案一最接近实时,但需要挂载 FTP;方案二更通用但有一定延迟;方案三适用于上传场景。

0

评论区