自动检测并清理无效路径脚本

wen 实用脚本 1

本文目录导读:

自动检测并清理无效路径脚本

  1. 基础版本:清理系统PATH中的无效路径
  2. 进阶版本:更全面的路径检测和清理
  3. 使用方法
  4. 功能特性
  5. 安全建议

我来为您提供一个自动检测并清理无效路径的脚本,这个脚本可以检查系统中配置的各种路径(如环境变量PATH、配置文件中的路径等)是否有效,并清理不存在的路径。

基础版本:清理系统PATH中的无效路径

#!/bin/bash
# 自动检测并清理无效路径脚本
# 版本:1.0
# 作者:AI助手
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 显示使用说明
usage() {
    echo "用法: $0 [选项]"
    echo "选项:"
    echo "  -p, --path     清理PATH环境变量中的无效路径"
    echo "  -l, --ldpath   清理LD_LIBRARY_PATH中的无效路径"
    echo "  -c, --config   清理指定配置文件中的路径"
    echo "  -a, --all      执行所有清理操作"
    echo "  -d, --dir DIR  清理指定目录中的无效符号链接"
    echo "  -h, --help     显示帮助信息"
    exit 1
}
# 检测路径是否存在
check_path() {
    local path="$1"
    if [ -d "$path" ] || [ -f "$path" ]; then
        return 0
    else
        return 1
    fi
}
# 清理环境变量中的无效路径
clean_env_path() {
    local var_name="$1"
    local var_value="${!var_name}"
    local new_value=""
    local cleaned=0
    local total=0
    echo -e "${YELLOW}正在清理 \$${var_name}...${NC}"
    IFS=':' read -ra paths <<< "$var_value"
    for path in "${paths[@]}"; do
        total=$((total + 1))
        if check_path "$path"; then
            if [ -z "$new_value" ]; then
                new_value="$path"
            else
                new_value="$new_value:$path"
            fi
        else
            echo -e "${RED}移除无效路径: $path${NC}"
            cleaned=$((cleaned + 1))
        fi
    done
    if [ $cleaned -gt 0 ]; then
        export "$var_name=$new_value"
        echo -e "${GREEN}已清理 $cleaned 个无效路径${NC}"
        echo -e "${GREEN}剩余 $((total - cleaned)) 个有效路径${NC}"
        # 更新到shell配置文件
        update_shell_config "$var_name" "$new_value"
    else
        echo -e "${GREEN}没有发现无效路径${NC}"
    fi
}
# 更新shell配置文件
update_shell_config() {
    local var_name="$1"
    local var_value="$2"
    local config_file=""
    # 检测使用的shell
    if [ -n "$ZSH_VERSION" ]; then
        config_file="$HOME/.zshrc"
    elif [ -n "$BASH_VERSION" ]; then
        config_file="$HOME/.bashrc"
    else
        config_file="$HOME/.profile"
    fi
    echo -e "${YELLOW}正在更新配置文件: $config_file${NC}"
    # 备份原配置文件
    cp "$config_file" "${config_file}.backup.$(date +%Y%m%d_%H%M%S)"
    # 更新配置
    if grep -q "export $var_name=" "$config_file"; then
        sed -i "s|export $var_name=.*|export $var_name=\"$var_value\"|g" "$config_file"
    else
        echo "export $var_name=\"$var_value\"" >> "$config_file"
    fi
    echo -e "${GREEN}配置文件已更新${NC}"
    echo -e "${YELLOW}请运行 'source $config_file' 或重新打开终端使更改生效${NC}"
}
# 清理指定目录中的无效符号链接
clean_symlinks() {
    local target_dir="$1"
    if [ ! -d "$target_dir" ]; then
        echo -e "${RED}错误: 目录不存在 - $target_dir${NC}"
        exit 1
    fi
    echo -e "${YELLOW}正在清理目录中的无效符号链接: $target_dir${NC}"
    local broken_links=0
    while IFS= read -r -d '' link; do
        if [ ! -e "$link" ]; then
            echo -e "${RED}发现无效链接: ${NC}$link"
            rm "$link" && echo -e "${GREEN}已删除${NC}" && broken_links=$((broken_links + 1))
        fi
    done < <(find "$target_dir" -type l -print0)
    if [ $broken_links -gt 0 ]; then
        echo -e "${GREEN}已清理 $broken_links 个无效符号链接${NC}"
    else
        echo -e "${GREEN}没有发现无效符号链接${NC}"
    fi
}
# 清理配置文件中的路径
clean_config_paths() {
    local config_file="$1"
    if [ ! -f "$config_file" ]; then
        echo -e "${RED}错误: 配置文件不存在 - $config_file${NC}"
        exit 1
    fi
    echo -e "${YELLOW}正在清理配置文件中的路径: $config_file${NC}"
    # 备份配置文件
    cp "$config_file" "${config_file}.backup.$(date +%Y%m%d_%H%M%S)"
    local temp_file=$(mktemp)
    local cleaned=0
    while IFS= read -r line; do
        # 提取路径(假设路径以/开头)
        path=$(echo "$line" | grep -oP '"(/[^"]*)"|(/[^\s]*)')
        if [ -n "$path" ]; then
            path=$(echo "$path" | tr -d '"')
            if check_path "$path"; then
                echo "$line" >> "$temp_file"
            else
                echo -e "${RED}移除无效路径相关配置: $line${NC}"
                cleaned=$((cleaned + 1))
            fi
        else
            echo "$line" >> "$temp_file"
        fi
    done < "$config_file"
    mv "$temp_file" "$config_file"
    if [ $cleaned -gt 0 ]; then
        echo -e "${GREEN}已清理 $cleaned 条包含无效路径的配置${NC}"
    else
        echo -e "${GREEN}没有发现无效路径配置${NC}"
    fi
}
# 主函数
main() {
    if [ $# -eq 0 ]; then
        usage
    fi
    while [ $# -gt 0 ]; do
        case "$1" in
            -p|--path)
                clean_env_path "PATH"
                shift
                ;;
            -l|--ldpath)
                clean_env_path "LD_LIBRARY_PATH"
                shift
                ;;
            -c|--config)
                if [ -z "$2" ]; then
                    echo -e "${RED}错误: 请指定配置文件路径${NC}"
                    exit 1
                fi
                clean_config_paths "$2"
                shift 2
                ;;
            -d|--dir)
                if [ -z "$2" ]; then
                    echo -e "${RED}错误: 请指定目录路径${NC}"
                    exit 1
                fi
                clean_symlinks "$2"
                shift 2
                ;;
            -a|--all)
                echo -e "${GREEN}开始全面清理...${NC}"
                clean_env_path "PATH"
                clean_env_path "LD_LIBRARY_PATH"
                # 检测常见配置文件
                for config in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.profile"; do
                    if [ -f "$config" ]; then
                        clean_config_paths "$config"
                    fi
                done
                # 清理/usr/local/bin中的无效链接
                clean_symlinks "/usr/local/bin"
                shift
                ;;
            -h|--help)
                usage
                ;;
            *)
                echo -e "${RED}未知选项: $1${NC}"
                usage
                ;;
        esac
    done
    echo -e "${GREEN}清理完成!${NC}"
}
# 运行主函数
main "$@"

进阶版本:更全面的路径检测和清理

#!/bin/bash
# 高级路径清理脚本
# 功能更全面,包含更多检测和清理选项
set -euo pipefail
# 全局变量
LOG_FILE="/tmp/path_cleaner_$(date +%Y%m%d_%H%M%S).log"
VERBOSE=false
DRY_RUN=false
# 日志函数
log() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
    if [ "$VERBOSE" = true ] || [ "$level" = "ERROR" ] || [ "$level" = "WARNING" ]; then
        echo "[$level] $message"
    fi
}
# 检测路径类型
path_type() {
    local path="$1"
    if [ -d "$path" ]; then
        echo "directory"
    elif [ -f "$path" ]; then
        echo "file"
    elif [ -L "$path" ]; then
        echo "symlink"
    else
        echo "invalid"
    fi
}
# 检查路径权限
check_permissions() {
    local path="$1"
    if [ -r "$path" ] && [ -x "$path" ]; then
        return 0
    fi
    return 1
}
# 清理系统级别的路径
clean_system_paths() {
    log "INFO" "开始清理系统级路径..."
    # 清理PATH
    IFS=':' read -ra paths <<< "$PATH"
    local new_path=""
    local removed=0
    for path in "${paths[@]}"; do
        if [ -d "$path" ]; then
            if [ -z "$new_path" ]; then
                new_path="$path"
            else
                new_path="$new_path:$path"
            fi
        else
            log "WARNING" "移除无效PATH: $path"
            removed=$((removed + 1))
        fi
    done
    if [ $removed -gt 0 ] && [ "$DRY_RUN" = false ]; then
        export PATH="$new_path"
        log "INFO" "已从PATH中移除 $removed 个无效路径"
    fi
    # 清理LD_LIBRARY_PATH
    if [ -n "${LD_LIBRARY_PATH:-}" ]; then
        IFS=':' read -ra libpaths <<< "$LD_LIBRARY_PATH"
        local new_libpath=""
        removed=0
        for path in "${libpaths[@]}"; do
            if [ -d "$path" ]; then
                if [ -z "$new_libpath" ]; then
                    new_libpath="$path"
                else
                    new_libpath="$new_libpath:$path"
                fi
            else
                log "WARNING" "移除无效LD_LIBRARY_PATH: $path"
                removed=$((removed + 1))
            fi
        done
        if [ $removed -gt 0 ] && [ "$DRY_RUN" = false ]; then
            export LD_LIBRARY_PATH="$new_libpath"
            log "INFO" "已从LD_LIBRARY_PATH中移除 $removed 个无效路径"
        fi
    fi
}
# 清理用户级别的路径
clean_user_paths() {
    log "INFO" "开始清理用户级路径..."
    local user_dirs=(
        "$HOME/bin"
        "$HOME/.local/bin"
        "$HOME/opt"
    )
    for dir in "${user_dirs[@]}"; do
        if [ -d "$dir" ]; then
            # 清理目录中的无效符号链接
            clean_symlinks_recursive "$dir"
        fi
    done
}
# 递归清理符号链接
clean_symlinks_recursive() {
    local dir="$1"
    log "INFO" "清理符号链接: $dir"
    find "$dir" -type l 2>/dev/null | while read -r link; do
        if [ ! -e "$link" ]; then
            target=$(readlink "$link")
            log "WARNING" "发现断开链接: $link -> $target"
            if [ "$DRY_RUN" = false ]; then
                rm "$link" && log "INFO" "已删除: $link"
            fi
        fi
    done
}
# 清理配置文件中的路径
clean_config_files() {
    log "INFO" "开始清理配置文件..."
    local config_files=(
        "$HOME/.bashrc"
        "$HOME/.bash_profile"
        "$HOME/.zshrc"
        "$HOME/.profile"
        "$HOME/.config/environment.d/*.conf"
    )
    for config in "${config_files[@]}"; do
        # 展开通配符
        for file in $config; do
            if [ -f "$file" ]; then
                log "INFO" "检查配置文件: $file"
                # 备份
                cp "$file" "${file}.backup"
                # 清理export PATH语句中的无效路径
                if grep -q "^export PATH=" "$file" 2>/dev/null; then
                    local current_path=$(grep "^export PATH=" "$file" | sed 's/^export PATH=//' | tr -d '"')
                    local new_path=""
                    local removed=0
                    IFS=':' read -ra paths <<< "$current_path"
                    for path in "${paths[@]}"; do
                        if [ -d "$(echo "$path" | sed 's/\$HOME/'"$HOME"'/g' | sed 's/\${HOME}/'"$HOME"'/g')" ]; then
                            if [ -z "$new_path" ]; then
                                new_path="$path"
                            else
                                new_path="$new_path:$path"
                            fi
                        else
                            log "WARNING" "配置文件中发现无效路径: $path"
                            removed=$((removed + 1))
                        fi
                    done
                    if [ $removed -gt 0 ] && [ "$DRY_RUN" = false ]; then
                        sed -i "s|^export PATH=.*|export PATH=\"$new_path\"|g" "$file"
                        log "INFO" "已更新配置文件: $file"
                    fi
                fi
            fi
        done
    done
}
# 检测重复路径
check_duplicate_paths() {
    log "INFO" "检测重复路径..."
    local vars=("PATH" "LD_LIBRARY_PATH" "PYTHONPATH" "MANPATH")
    for var in "${vars[@]}"; do
        local value="${!var:-}"
        if [ -n "$value" ]; then
            local duplicates=$(echo "$value" | tr ':' '\n' | sort | uniq -d)
            if [ -n "$duplicates" ]; then
                log "WARNING" "$var 中发现重复路径:"
                echo "$duplicates" | while read -r dup; do
                    log "WARNING" "  - $dup"
                done
                # 去重
                if [ "$DRY_RUN" = false ]; then
                    local new_value=$(echo "$value" | tr ':' '\n' | sort -u | tr '\n' ':' | sed 's/:$//')
                    export "$var=$new_value"
                    log "INFO" "已去除 $var 中的重复路径"
                fi
            fi
        fi
    done
}
# 显示统计信息
show_statistics() {
    echo "========================================"
    echo "路径清理统计信息"
    echo "========================================"
    echo "环境变量数量:"
    echo "  PATH: $(echo $PATH | tr ':' '\n' | wc -l) 个路径"
    echo "  LD_LIBRARY_PATH: $(echo ${LD_LIBRARY_PATH:-} | tr ':' '\n' | wc -l) 个路径"
    echo "配置文件备份:"
    ls -la "$HOME"/*.backup 2>/dev/null | wc -l
    echo "日志文件: $LOG_FILE"
    echo "========================================"
}
# 主清理函数
clean_paths() {
    log "INFO" "========== 开始路径清理 =========="
    clean_system_paths
    clean_user_paths
    clean_config_files
    check_duplicate_paths
    log "INFO" "========== 路径清理完成 =========="
    show_statistics
}
# 显示帮助信息
show_help() {
    echo "用法: $0 [选项]"
    echo "选项:"
    echo "  -v, --verbose    详细输出模式"
    echo "  -n, --dry-run    模拟运行,不执行实际清理"
    echo "  -l, --log FILE   指定日志文件"
    echo "  -h, --help       显示帮助信息"
    echo ""
    echo "示例:"
    echo "  $0               执行标准清理"
    echo "  $0 -v            详细模式清理"
    echo "  $0 -n            模拟运行,查看将要清理的内容"
    echo "  $0 -l /tmp/mylog.log  指定日志文件"
}
# 主函数
main() {
    # 解析参数
    while [ $# -gt 0 ]; do
        case "$1" in
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -n|--dry-run)
                DRY_RUN=true
                shift
                ;;
            -l|--log)
                LOG_FILE="$2"
                shift 2
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                echo "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
    echo "路径清理工具 v2.0"
    echo "运行模式: $([ "$DRY_RUN" = true ] && echo '模拟运行' || echo '实际执行')"
    echo "日志文件: $LOG_FILE"
    echo ""
    # 请求确认
    if [ "$DRY_RUN" = false ]; then
        read -p "是否继续执行清理? (y/N): " confirm
        if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
            echo "操作已取消"
            exit 0
        fi
    fi
    # 执行清理
    clean_paths
}
# 执行主函数
main "$@"

使用方法

基础脚本使用:

# 清理PATH中的无效路径
./clean_paths.sh -p
# 清理所有
./clean_paths.sh -a
# 清理指定目录中的无效符号链接
./clean_paths.sh -d /usr/local/bin

高级脚本使用:

# 模拟运行(查看将要清理的内容)
./clean_paths_advanced.sh -n
# 详细模式运行
./clean_paths_advanced.sh -v
# 标准运行
./clean_paths_advanced.sh

功能特性

  1. 自动检测无效路径:检查所有环境变量和配置文件中的路径
  2. 备份机制:自动备份配置文件,防止误操作
  3. 符号链接清理:检测和清理断开的符号链接
  4. 重复路径检测:识别并清理重复的路径
  5. 多配置文件支持:支持bash、zsh等多种shell配置文件
  6. 详细日志:记录所有操作,便于问题排查

安全建议

  1. 首次使用时建议先使用 -n 参数进行模拟运行
  2. 脚本会自动创建配置文件备份,但仍建议手动备份重要配置
  3. 可以定期运行此脚本(如每月一次)来保持系统路径的整洁

这个脚本可以帮助您自动检测和清理系统中的无效路径,提高系统性能和稳定性。

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