本文目录导读:

我来为您提供一个自动检测并清理无效路径的脚本,这个脚本可以检查系统中配置的各种路径(如环境变量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
功能特性
- 自动检测无效路径:检查所有环境变量和配置文件中的路径
- 备份机制:自动备份配置文件,防止误操作
- 符号链接清理:检测和清理断开的符号链接
- 重复路径检测:识别并清理重复的路径
- 多配置文件支持:支持bash、zsh等多种shell配置文件
- 详细日志:记录所有操作,便于问题排查
安全建议
- 首次使用时建议先使用
-n参数进行模拟运行 - 脚本会自动创建配置文件备份,但仍建议手动备份重要配置
- 可以定期运行此脚本(如每月一次)来保持系统路径的整洁
这个脚本可以帮助您自动检测和清理系统中的无效路径,提高系统性能和稳定性。