如何编写自动下载并校验脚本

wen 实用脚本 1

本文目录导读:

如何编写自动下载并校验脚本

  1. Python版本(跨平台)
  2. Bash版本(Linux/macOS)
  3. 使用示例
  4. 功能特点
  5. 批量下载校验(高级用法)

我来帮您编写一个自动下载并校验文件的脚本,这里提供Python和Bash两个版本,包含常见的MD5/SHA256校验方式。

Python版本(跨平台)

#!/usr/bin/env python3
"""
自动下载并校验脚本
支持:MD5、SHA1、SHA256、SHA512校验
"""
import hashlib
import os
import sys
import requests
from urllib.parse import urlparse
import argparse
from tqdm import tqdm
def calculate_hash(filepath, hash_type='sha256'):
    """计算文件的哈希值"""
    hash_func = getattr(hashlib, hash_type)()
    # 分块读取大文件
    block_size = 65536
    with open(filepath, 'rb') as f:
        for chunk in iter(lambda: f.read(block_size), b''):
            hash_func.update(chunk)
    return hash_func.hexdigest()
def download_file(url, save_path=None, verify_ssl=True):
    """下载文件并显示进度"""
    if save_path is None:
        # 从URL提取文件名
        filename = os.path.basename(urlparse(url).path)
        if not filename:
            filename = 'downloaded_file'
        save_path = filename
    print(f"正在下载: {url}")
    print(f"保存到: {save_path}")
    try:
        response = requests.get(url, stream=True, verify=verify_ssl)
        response.raise_for_status()
        # 获取文件总大小
        total_size = int(response.headers.get('content-length', 0))
        # 使用tqdm显示进度条
        with open(save_path, 'wb') as f:
            with tqdm(total=total_size, unit='B', unit_scale=True, desc=save_path) as pbar:
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        f.write(chunk)
                        pbar.update(len(chunk))
        print(f"下载完成: {save_path}")
        return save_path
    except requests.exceptions.RequestException as e:
        print(f"下载失败: {e}", file=sys.stderr)
        return None
def verify_file(filepath, expected_hash, hash_type='sha256'):
    """验证文件完整性"""
    print(f"正在计算{hash_type.upper()}值...")
    actual_hash = calculate_hash(filepath, hash_type)
    print(f"预期{hash_type.upper()}: {expected_hash}")
    print(f"实际{hash_type.upper()}: {actual_hash}")
    if actual_hash.lower() == expected_hash.lower():
        print("✓ 校验成功:文件完整")
        return True
    else:
        print("✗ 校验失败:文件可能已损坏")
        return False
def main():
    parser = argparse.ArgumentParser(description='自动下载并校验文件')
    parser.add_argument('url', help='下载文件的URL')
    parser.add_argument('-o', '--output', help='保存路径(可选)')
    parser.add_argument('-c', '--check', help='校验哈希值')
    parser.add_argument('-t', '--type', default='sha256', 
                       choices=['md5', 'sha1', 'sha256', 'sha512'],
                       help='哈希类型(默认:sha256)')
    parser.add_argument('--no-ssl-verify', action='store_true',
                       help='禁用SSL证书验证')
    args = parser.parse_args()
    # 下载文件
    filepath = download_file(args.url, args.output, not args.no_ssl_verify)
    if filepath is None:
        sys.exit(1)
    # 如果需要校验
    if args.check:
        if verify_file(filepath, args.check, args.type):
            print("操作完成:文件下载并验证成功")
        else:
            print("警告:文件校验失败", file=sys.stderr)
            if input("是否删除文件?(y/n): ").lower() == 'y':
                os.remove(filepath)
                print("文件已删除")
            sys.exit(1)
    else:
        print(f"文件已下载到: {filepath}")
if __name__ == '__main__':
    main()

Bash版本(Linux/macOS)

#!/bin/bash
"""
自动下载并校验脚本(Bash版本)
支持:MD5、SHA1、SHA256、SHA512校验
"""
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 显示帮助信息
usage() {
    echo "用法: $0 -u URL [-o OUTPUT] [-c CHECKSUM] [-t TYPE]"
    echo ""
    echo "选项:"
    echo "  -u URL       下载文件的URL"
    echo "  -o OUTPUT    保存路径(可选)"
    echo "  -c CHECKSUM  校验哈希值"
    echo "  -t TYPE      哈希类型:md5|sha1|sha256|sha512(默认:sha256)"
    echo "  -h           显示帮助信息"
    exit 1
}
# 下载文件
download_file() {
    local url=$1
    local output=$2
    echo -e "${YELLOW}正在下载: ${url}${NC}"
    if [ -z "$output" ]; then
        output=$(basename "$url")
        # 如果URL以/使用默认名称
        [ -z "$output" ] && output="downloaded_file"
    fi
    echo -e "${YELLOW}保存到: ${output}${NC}"
    # 使用wget或curl下载
    if command -v wget &> /dev/null; then
        wget -O "$output" --progress=bar:force "$url" 2>&1
    elif command -v curl &> /dev/null; then
        curl -L -o "$output" --progress-bar "$url"
    else
        echo -e "${RED}错误: 需要安装wget或curl${NC}"
        return 1
    fi
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}下载完成: ${output}${NC}"
        echo "$output"
    else
        echo -e "${RED}下载失败${NC}"
        return 1
    fi
}
# 计算哈希值
calculate_hash() {
    local file=$1
    local hash_type=$2
    case $hash_type in
        md5)
            md5sum "$file" | cut -d' ' -f1
            ;;
        sha1)
            sha1sum "$file" | cut -d' ' -f1
            ;;
        sha256)
            sha256sum "$file" | cut -d' ' -f1
            ;;
        sha512)
            sha512sum "$file" | cut -d' ' -f1
            ;;
        *)
            echo -e "${RED}不支持的哈希类型: ${hash_type}${NC}"
            return 1
            ;;
    esac
}
# 验证文件
verify_file() {
    local file=$1
    local expected_hash=$2
    local hash_type=$3
    echo -e "${YELLOW}正在计算${hash_type^^}值...${NC}"
    actual_hash=$(calculate_hash "$file" "$hash_type")
    echo -e "预期${hash_type^^}: ${expected_hash}"
    echo -e "实际${hash_type^^}: ${actual_hash}"
    if [ "${actual_hash,,}" = "${expected_hash,,}" ]; then
        echo -e "${GREEN}✓ 校验成功:文件完整${NC}"
        return 0
    else
        echo -e "${RED}✗ 校验失败:文件可能已损坏${NC}"
        return 1
    fi
}
# 主函数
main() {
    local url=""
    local output=""
    local checksum=""
    local hash_type="sha256"
    # 解析命令行参数
    while getopts "u:o:c:t:h" opt; do
        case $opt in
            u) url="$OPTARG" ;;
            o) output="$OPTARG" ;;
            c) checksum="$OPTARG" ;;
            t) hash_type="$OPTARG" ;;
            h) usage ;;
            *) usage ;;
        esac
    done
    # 检查URL参数
    if [ -z "$url" ]; then
        echo -e "${RED}错误: 必须指定URL${NC}"
        usage
    fi
    # 检查哈希类型
    if [[ ! "$hash_type" =~ ^(md5|sha1|sha256|sha512)$ ]]; then
        echo -e "${RED}错误: 不支持的哈希类型${NC}"
        usage
    fi
    # 下载文件
    filepath=$(download_file "$url" "$output")
    if [ $? -ne 0 ] || [ -z "$filepath" ]; then
        exit 1
    fi
    # 如果需要校验
    if [ -n "$checksum" ]; then
        if verify_file "$filepath" "$checksum" "$hash_type"; then
            echo -e "${GREEN}操作完成:文件下载并验证成功${NC}"
        else
            echo -e "${RED}警告:文件校验失败${NC}"
            read -p "是否删除文件?(y/n): " answer
            if [ "${answer,,}" = "y" ]; then
                rm -f "$filepath"
                echo "文件已删除"
            fi
            exit 1
        fi
    else
        echo -e "${GREEN}文件已下载到: ${filepath}${NC}"
    fi
}
# 执行主函数
main "$@"

使用示例

Python版本

# 安装依赖
pip install requests tqdm
# 下载并校验(SHA256)
python download_verify.py https://example.com/file.zip -c "预期SHA256值" -t sha256
# 仅下载(指定文件名)
python download_verify.py https://example.com/file.zip -o myfile.zip
# 禁用SSL验证(不推荐)
python download_verify.py https://example.com/file.zip --no-ssl-verify

Bash版本

# 给脚本执行权限
chmod +x download_verify.sh
# 下载并校验
./download_verify.sh -u https://example.com/file.zip -c "预期SHA256值" -t sha256
# 仅下载(指定文件名)
./download_verify.sh -u https://example.com/file.zip -o myfile.zip
# 使用MD5校验
./download_verify.sh -u https://example.com/file.zip -c "预期MD5值" -t md5

功能特点

  1. 支持多种哈希算法:MD5、SHA1、SHA256、SHA512
  2. 带进度条显示:显示下载进度和速度
  3. 断点续传(Python版本可扩展)
  4. 错误处理:网络错误、文件损坏等异常处理
  5. 跨平台支持:Python版本可在Windows/Linux/macOS运行

批量下载校验(高级用法)

如果您需要批量下载多个文件,可以扩展Python脚本:

# 批量下载配置文件示例
batch_config = [
    {
        'url': 'https://example.com/file1.zip',
        'hash': 'abc123...',
        'type': 'sha256'
    },
    {
        'url': 'https://example.com/file2.tar.gz',
        'hash': 'def456...',
        'type': 'sha512'
    }
]
for item in batch_config:
    filepath = download_file(item['url'])
    if filepath and item.get('hash'):
        verify_file(filepath, item['hash'], item.get('type', 'sha256'))

这样可以轻松集成到自动化部署流程中。

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