如何编写FTP上传下载脚本

wen 实用脚本 27

本文目录导读:

如何编写FTP上传下载脚本

  1. 使用批处理脚本(Windows)
  2. 使用Shell脚本(Linux/Unix)
  3. 使用Python脚本(跨平台)
  4. 使用lftp(增强型FTP客户端)
  5. 使用curl命令
  6. 完整的Python脚本(带异常处理和日志)
  7. 安全建议

我来介绍几种常见的方式来编写FTP上传下载脚本:

使用批处理脚本(Windows)

上传脚本

@echo off
echo open ftp.example.com> ftp.txt
echo username>> ftp.txt
echo password>> ftp.txt
echo binary>> ftp.txt
echo cd /remote/path>> ftp.txt
echo put local_file.txt>> ftp.txt
echo quit>> ftp.txt
ftp -s:ftp.txt
del ftp.txt

下载脚本

@echo off
echo open ftp.example.com> ftp.txt
echo username>> ftp.txt
echo password>> ftp.txt
echo binary>> ftp.txt
echo cd /remote/path>> ftp.txt
echo get remote_file.txt>> ftp.txt
echo quit>> ftp.txt
ftp -s:ftp.txt
del ftp.txt

使用Shell脚本(Linux/Unix)

上传脚本

#!/bin/bash
HOST='ftp.example.com'
USER='username'
PASS='password'
LOCAL_FILE='/path/to/local/file.txt'
REMOTE_PATH='/remote/path/'
ftp -n $HOST << END_SCRIPT
quote USER $USER
quote PASS $PASS
binary
cd $REMOTE_PATH
put $LOCAL_FILE
quit
END_SCRIPT

下载脚本

#!/bin/bash
HOST='ftp.example.com'
USER='username'
PASS='password'
REMOTE_FILE='/remote/path/file.txt'
LOCAL_PATH='/local/path/'
ftp -n $HOST << END_SCRIPT
quote USER $USER
quote PASS $PASS
binary
cd $(dirname $REMOTE_FILE)
get $(basename $REMOTE_FILE) $LOCAL_PATH
quit
END_SCRIPT

使用Python脚本(跨平台)

Python FTP上传下载脚本

from ftplib import FTP
import os
class FTPManager:
    def __init__(self, host, username, password):
        self.host = host
        self.username = username
        self.password = password
        self.ftp = None
    def connect(self):
        """连接到FTP服务器"""
        try:
            self.ftp = FTP(self.host)
            self.ftp.login(self.username, self.password)
            print(f"成功连接到 {self.host}")
            return True
        except Exception as e:
            print(f"连接失败: {e}")
            return False
    def disconnect(self):
        """断开连接"""
        if self.ftp:
            self.ftp.quit()
            print("已断开连接")
    def upload_file(self, local_path, remote_path):
        """上传文件"""
        try:
            with open(local_path, 'rb') as file:
                self.ftp.storbinary(f'STOR {remote_path}', file)
            print(f"上传成功: {local_path} -> {remote_path}")
            return True
        except Exception as e:
            print(f"上传失败: {e}")
            return False
    def download_file(self, remote_path, local_path):
        """下载文件"""
        try:
            with open(local_path, 'wb') as file:
                self.ftp.retrbinary(f'RETR {remote_path}', file.write)
            print(f"下载成功: {remote_path} -> {local_path}")
            return True
        except Exception as e:
            print(f"下载失败: {e}")
            return False
    def list_files(self, path='.'):
        """列出文件列表"""
        try:
            files = []
            self.ftp.dir(path, files.append)
            return files
        except Exception as e:
            print(f"列出文件失败: {e}")
            return []
# 使用示例
def main():
    # 配置
    FTP_CONFIG = {
        'host': 'ftp.example.com',
        'username': 'your_username',
        'password': 'your_password'
    }
    # 创建FTP管理器
    ftp_manager = FTPManager(**FTP_CONFIG)
    # 连接
    if ftp_manager.connect():
        # 上传文件
        ftp_manager.upload_file('local_file.txt', 'remote_file.txt')
        # 下载文件
        ftp_manager.download_file('remote_file.txt', 'downloaded_file.txt')
        # 列出文件
        files = ftp_manager.list_files()
        print("远程文件列表:")
        for file in files:
            print(file)
        # 断开连接
        ftp_manager.disconnect()
if __name__ == "__main__":
    main()

使用lftp(增强型FTP客户端)

#!/bin/bash
# LFTP 批量上传/下载脚本
# 批量上传目录
lftp -u username,password ftp.example.com -e "
set ftp:ssl-allow no
mirror -R /local/directory/ /remote/directory/
quit
"
# 批量下载目录
lftp -u username,password ftp.example.com -e "
set ftp:ssl-allow no
mirror /remote/directory/ /local/directory/
quit
"

使用curl命令

上传文件

curl -T local_file.txt ftp://ftp.example.com/ --user username:password

下载文件

curl -o local_file.txt ftp://ftp.example.com/remote_file.txt --user username:password

完整的Python脚本(带异常处理和日志)

import logging
from ftplib import FTP, error_perm
import os
from datetime import datetime
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class FTPTransfer:
    def __init__(self, host, port=21, username='anonymous', password='anonymous@'):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.ftp = None
    def __enter__(self):
        self.connect()
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.disconnect()
    def connect(self):
        """建立FTP连接"""
        try:
            self.ftp = FTP()
            self.ftp.connect(self.host, self.port)
            self.ftp.login(self.username, self.password)
            logger.info(f"成功连接到 {self.host}:{self.port}")
            return True
        except Exception as e:
            logger.error(f"连接失败: {e}")
            return False
    def disconnect(self):
        """断开连接"""
        if self.ftp:
            self.ftp.quit()
            logger.info("连接已关闭")
    def upload(self, local_file, remote_file=None):
        """上传文件"""
        if remote_file is None:
            remote_file = os.path.basename(local_file)
        try:
            with open(local_file, 'rb') as f:
                self.ftp.storbinary(f'STOR {remote_file}', f)
            logger.info(f"上传成功: {local_file} -> {remote_file}")
            return True
        except FileNotFoundError:
            logger.error(f"本地文件不存在: {local_file}")
        except error_perm as e:
            logger.error(f"FTP权限错误: {e}")
        except Exception as e:
            logger.error(f"上传失败: {e}")
        return False
    def download(self, remote_file, local_file=None):
        """下载文件"""
        if local_file is None:
            local_file = os.path.basename(remote_file)
        try:
            with open(local_file, 'wb') as f:
                self.ftp.retrbinary(f'RETR {remote_file}', f.write)
            logger.info(f"下载成功: {remote_file} -> {local_file}")
            return True
        except error_perm as e:
            logger.error(f"FTP权限错误: {e}")
        except Exception as e:
            logger.error(f"下载失败: {e}")
        return False
    def upload_directory(self, local_dir, remote_dir):
        """上传整个目录"""
        if not os.path.exists(local_dir):
            logger.error(f"本地目录不存在: {local_dir}")
            return False
        try:
            self.ftp.cwd(remote_dir)
        except:
            self.ftp.mkd(remote_dir)
            self.ftp.cwd(remote_dir)
        for item in os.listdir(local_dir):
            local_path = os.path.join(local_dir, item)
            if os.path.isfile(local_path):
                if not self.upload(local_path, item):
                    return False
            elif os.path.isdir(local_path):
                if not self.upload_directory(local_path, item):
                    return False
        self.ftp.cwd('..')
        return True
# 使用示例
def main():
    config = {
        'host': 'ftp.example.com',
        'port': 21,
        'username': 'user',
        'password': 'pass'
    }
    with FTPTransfer(**config) as ftp:
        # 上传文件
        ftp.upload('local.txt', 'remote.txt')
        # 下载文件
        ftp.download('remote.txt', 'downloaded.txt')
        # 上传目录
        ftp.upload_directory('local_folder', 'remote_folder')
if __name__ == "__main__":
    main()

安全建议

  1. 使用SFTP/SCP替代FTP:FTP传输不加密,建议使用SFTP
  2. 避免硬编码密码:使用环境变量或配置文件
  3. 添加错误处理:确保脚本有完善的异常处理
  4. 使用日志记录:记录所有传输操作
  5. 验证文件完整性:传输后校验MD5

选择哪种方式取决于你的操作系统、需求和技术栈,对于简单的任务,批处理或shell脚本就够了;对于复杂的应用,Python脚本更灵活。

抱歉,评论功能暂时关闭!