如何用脚本检查并安装缺失的软件依赖?

wen 实用脚本 43

本文目录导读:

如何用脚本检查并安装缺失的软件依赖?

  1. Python 脚本检查安装包
  2. Bash 脚本 - Linux 系统依赖检查
  3. 跨平台 Node.js 脚本
  4. 完整的 Python 依赖管理脚本
  5. 使用建议

Python 脚本检查安装包

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import importlib
import subprocess
import sys
def check_and_install_packages(packages):
    """
    检查并安装Python包
    """
    missing_packages = []
    for package in packages:
        try:
            # 尝试导入包
            importlib.import_module(package.replace('-', '_'))
            print(f"✅ {package} 已安装")
        except ImportError:
            missing_packages.append(package)
            print(f"❌ {package} 未安装")
    if missing_packages:
        print(f"\n正在安装缺失的包: {', '.join(missing_packages)}")
        for package in missing_packages:
            try:
                subprocess.check_call([sys.executable, "-m", "pip", "install", package])
                print(f"✅ {package} 安装成功")
            except subprocess.CalledProcessError:
                print(f"❌ {package} 安装失败")
    else:
        print("\n所有依赖都已安装!")
# 使用示例
required_packages = ["requests", "numpy", "pandas", "flask"]
check_and_install_packages(required_packages)

Bash 脚本 - Linux 系统依赖检查

#!/bin/bash
# 系统依赖检查脚本
# 适用于 Debian/Ubuntu 系统
check_and_install() {
    local package=$1
    local install_command=$2
    if command -v $package &> /dev/null; then
        echo "✅ $package 已安装"
    else
        echo "❌ $package 未安装,正在安装..."
        eval $install_command
        if [ $? -eq 0 ]; then
            echo "✅ $package 安装成功"
        else
            echo "❌ $package 安装失败"
            exit 1
        fi
    fi
}
# 定义需要检查的软件和安装命令
echo "开始检查系统依赖..."
# 检查 curl
check_and_install "curl" "sudo apt-get install -y curl"
# 检查 git
check_and_install "git" "sudo apt-get install -y git"
# 检查 nodejs
check_and_install "node" "curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && sudo apt-get install -y nodejs"
# 检查 docker
check_and_install "docker" "sudo apt-get install -y docker.io"
# 检查 nginx
check_and_install "nginx" "sudo apt-get install -y nginx"
echo "所有依赖检查完成!"

跨平台 Node.js 脚本

#!/usr/bin/env node
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
class DependencyChecker {
    constructor() {
        this.os = process.platform;
    }
    checkCommand(command) {
        try {
            execSync(`which ${command} || where ${command}`, { stdio: 'pipe' });
            return true;
        } catch (error) {
            return false;
        }
    }
    installPackage(package) {
        console.log(`正在安装 ${package}...`);
        let installCommand;
        if (this.os === 'linux') {
            const distro = this.getLinuxDistro();
            installCommand = this.getLinuxInstallCommand(distro, package);
        } else if (this.os === 'darwin') {
            installCommand = `brew install ${package}`;
        } else if (this.os === 'win32') {
            installCommand = `choco install ${package} -y`;
        } else {
            console.log(`不支持的操作系统: ${this.os}`);
            return false;
        }
        try {
            execSync(installCommand, { stdio: 'inherit' });
            console.log(`✅ ${package} 安装成功`);
            return true;
        } catch (error) {
            console.log(`❌ ${package} 安装失败`);
            return false;
        }
    }
    getLinuxDistro() {
        try {
            const content = execSync('cat /etc/os-release').toString();
            if (content.includes('Ubuntu') || content.includes('Debian')) return 'debian';
            if (content.includes('CentOS') || content.includes('RHEL')) return 'rhel';
            if (content.includes('Fedora')) return 'fedora';
            if (content.includes('Arch')) return 'arch';
            return 'unknown';
        } catch (error) {
            return 'unknown';
        }
    }
    getLinuxInstallCommand(distro, package) {
        const commands = {
            'debian': `sudo apt-get update && sudo apt-get install -y ${package}`,
            'rhel': `sudo yum install -y ${package}`,
            'fedora': `sudo dnf install -y ${package}`,
            'arch': `sudo pacman -S ${package} --noconfirm`
        };
        return commands[distro] || `sudo apt-get install -y ${package}`;
    }
    checkAndInstall(dependencies) {
        console.log('开始检查依赖...\n');
        dependencies.forEach(dep => {
            if (this.checkCommand(dep)) {
                console.log(`✅ ${dep} 已安装`);
            } else {
                console.log(`❌ ${dep} 未安装`);
                this.installPackage(dep);
            }
        });
        console.log('\n依赖检查完成!');
    }
}
// 使用示例
const checker = new DependencyChecker();
const requiredDeps = ['git', 'node', 'npm', 'python3'];
checker.checkAndInstall(requiredDeps);

完整的 Python 依赖管理脚本

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import importlib
import subprocess
import sys
import os
from typing import List, Dict, Optional
class DependencyManager:
    """依赖管理类"""
    def __init__(self):
        self.pip = [sys.executable, "-m", "pip"]
    def read_requirements(self, filepath: str = "requirements.txt") -> List[str]:
        """读取 requirements.txt 文件"""
        if not os.path.exists(filepath):
            print(f"文件 {filepath} 不存在")
            return []
        with open(filepath, 'r', encoding='utf-8') as f:
            return [line.strip() for line in f if line.strip() and not line.startswith('#')]
    def check_package(self, package: str) -> bool:
        """检查单个包是否安装"""
        try:
            # 处理带版本的包名,如 requests==2.28.0
            package_name = package.split('==')[0].split('>=')[0].split('<=')[0]
            # 将横线转换为下划线
            package_name = package_name.replace('-', '_')
            importlib.import_module(package_name)
            return True
        except ImportError:
            return False
    def install_package(self, package: str) -> bool:
        """安装单个包"""
        try:
            subprocess.check_call(self.pip + ["install", package])
            return True
        except subprocess.CalledProcessError:
            return False
    def check_and_install(self, packages: List[str], auto_install: bool = True) -> Dict[str, str]:
        """
        检查并安装依赖
        返回: {package: status}
        status: 'installed', 'installed_now', 'failed'
        """
        result = {}
        missing = []
        print("检查依赖中...\n")
        for package in packages:
            if self.check_package(package):
                result[package] = 'installed'
                print(f"✅ {package} 已安装")
            else:
                result[package] = 'pending'
                missing.append(package)
                print(f"❌ {package} 未安装")
        if missing and auto_install:
            print(f"\n发现 {len(missing)} 个缺失的依赖,正在自动安装...\n")
            for package in missing:
                print(f"正在安装 {package}...")
                if self.install_package(package):
                    result[package] = 'installed_now'
                    print(f"✅ {package} 安装成功")
                else:
                    result[package] = 'failed'
                    print(f"❌ {package} 安装失败")
        return result
    def update_all_packages(self) -> bool:
        """更新所有已安装的包"""
        try:
            subprocess.check_call(self.pip + ["list", "--outdated", "--format=columns"])
            response = input("\n是否更新所有过时的包?(y/n): ")
            if response.lower() == 'y':
                # 获取需要更新的包列表
                outdated = subprocess.check_output(
                    self.pip + ["list", "--outdated", "--format=freeze"]
                ).decode().strip().split('\n')
                for pkg in outdated:
                    pkg_name = pkg.split('==')[0]
                    print(f"正在更新 {pkg_name}...")
                    self.install_package(f"{pkg_name} --upgrade")
                print("所有包更新完成!")
            return True
        except Exception as e:
            print(f"更新失败: {e}")
            return False
# 使用示例
def main():
    manager = DependencyManager()
    # 方式1:从 requirements.txt 文件读取
    packages = manager.read_requirements()
    if packages:
        print("从 requirements.txt 读取依赖:")
        for pkg in packages:
            print(f"  - {pkg}")
        print()
    else:
        # 方式2:手动指定依赖
        packages = [
            "requests",
            "flask",
            "numpy",
            "pandas",
            "matplotlib"
        ]
    # 检查并安装
    results = manager.check_and_install(packages, auto_install=True)
    # 统计结果
    installed = sum(1 for v in results.values() if v in ['installed', 'installed_now'])
    failed = sum(1 for v in results.values() if v == 'failed')
    print(f"\n安装统计:")
    print(f"✅ 成功: {installed}")
    print(f"❌ 失败: {failed}")
    print(f"📊 总计: {len(results)}")
if __name__ == "__main__":
    main()

使用建议

  1. 选择适合的脚本

    • Python 项目:使用 Python 脚本
    • 系统工具:使用 Bash 脚本
    • 跨平台需求:使用 Node.js 脚本
  2. 安全考虑

    • 始终验证来源
    • 使用 sudo 时要谨慎
    • 添加错误处理
  3. 最佳实践

    • 维护 requirements.txtpackage.json
    • 使用虚拟环境
    • 定期更新依赖
    • 添加日志记录

需要我帮你定制特定场景的依赖检查脚本吗?

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