Debian下使用AppImage创建图标问题
用起来不是很方便,于是写了个脚本帮忙添加到开始菜单:
#!/bin/bash
# 配置变量
ICONS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/icons"
APPLICATIONS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
ICON_SIZES=("256x256" "128x128" "64x64" "48x48" "32x32")
DEFAULT_ICON="application-x-executable"
DEFAULT_CATEGORY="Utility"
REFRESH_DELAY=2 # 刷新延迟时间(秒)
NEEDS_REFRESH=false # 是否需要刷新标志
BATCH_MODE=false # 批量模式标志
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
error() {
log "错误: $1" >&2
exit 1
}
# 检查命令是否存在
check_command() {
if ! command -v "$1" >/dev/null 2>&1; then
error "未找到命令: $1"
fi
}
# 检查必要的命令
check_command update-desktop-database
check_command gtk-update-icon-cache
# 显示帮助信息
show_help() {
echo "AppImage 安装器"
echo "使用方法: $0 [选项] <AppImage文件路径或目录>"
echo ""
echo "选项:"
echo " -h, --help 显示此帮助信息"
echo " -u, --uninstall 卸载指定的 AppImage"
echo " -f, --force 强制安装/卸载"
echo " -v, --verbose 显示详细信息"
echo " -d, --delay 设置刷新延迟时间(秒)"
echo " -b, --batch 批量安装模式"
echo ""
echo "示例:"
echo " $0 ./myapp.AppImage # 安装单个 AppImage"
echo " $0 -b ./appimages/ # 批量安装目录下的所有 AppImage"
echo " $0 -u myapp # 卸载 AppImage"
echo " $0 -d 5 ./myapp.AppImage # 设置5秒延迟刷新"
}
# 解析命令行参数
UNINSTALL=false
FORCE=false
VERBOSE=false
while [[ $# -gt 0 ]]; do
case $1 in
-h | --help)
show_help
exit 0
;;
-u | --uninstall)
UNINSTALL=true
shift
;;
-f | --force)
FORCE=true
shift
;;
-v | --verbose)
VERBOSE=true
shift
;;
-d | --delay)
REFRESH_DELAY="$2"
shift 2
;;
-b | --batch)
BATCH_MODE=true
shift
;;
*)
APPIMAGE_PATH="$1"
shift
;;
esac
done
# 检查是否提供了参数
if [ -z "$APPIMAGE_PATH" ]; then
show_help
error "未提供 AppImage 文件路径或目录"
fi
# 获取绝对路径
APPIMAGE_PATH=$(realpath "$APPIMAGE_PATH")
# 如果是卸载模式
if [ "$UNINSTALL" = true ]; then
APP_NAME="$APPIMAGE_PATH"
if [ -f "$APPLICATIONS_DIR/$APP_NAME.desktop" ]; then
log "正在卸载 $APP_NAME..."
rm -f "$APPLICATIONS_DIR/$APP_NAME.desktop"
rm -f "$ICONS_DIR/$APP_NAME.png"
NEEDS_REFRESH=true
log "卸载完成!"
else
error "未找到应用程序: $APP_NAME"
fi
exit 0
fi
# 安装单个 AppImage 的函数
install_appimage() {
local appimage_path="$1"
local app_name=$(basename "$appimage_path" .AppImage)
# 检查文件是否存在
if [ ! -f "$appimage_path" ]; then
log "警告: 文件 '$appimage_path' 不存在,跳过"
return 1
fi
# 检查文件是否为 AppImage
if [[ ! "$appimage_path" =~ \.AppImage$ ]]; then
log "警告: 文件 '$appimage_path' 不是 AppImage 格式,跳过"
return 1
fi
# 检查是否已安装
if [ -f "$APPLICATIONS_DIR/$app_name.desktop" ] && [ "$FORCE" != true ]; then
log "应用程序 '$app_name' 已安装,跳过"
return 0
fi
# 创建临时目录
local temp_dir=$(mktemp -d)
trap 'rm -rf "$temp_dir"' EXIT
# 提取图标和窗口类名
log "正在处理 $app_name..."
cd "$temp_dir"
"$appimage_path" --appimage-extract >/dev/null 2>&1
# 尝试从 .desktop 文件中获取窗口类名和类别
local desktop_file=$(find squashfs-root -name "*.desktop" -type f 2>/dev/null | head -n 1)
local wm_class=""
local categories=""
if [ -n "$desktop_file" ]; then
wm_class=$(grep -m 1 "StartupWMClass=" "$desktop_file" | cut -d'=' -f2)
categories=$(grep -m 1 "Categories=" "$desktop_file" | cut -d'=' -f2)
fi
if [ -z "$wm_class" ]; then
wm_class=$(echo "$app_name" | tr '[:upper:]' '[:lower:]')
fi
if [ -z "$categories" ]; then
categories="$DEFAULT_CATEGORY"
fi
# 提取图标
local icon_path=""
local icon_name="$DEFAULT_ICON"
# 检查是否已有图标
if [ -f "$ICONS_DIR/$app_name.png" ] || [ -f "$ICONS_DIR/$app_name.svg" ]; then
icon_name="$app_name"
else
# 搜索所有可能的图标位置
for base_path in "${ICON_PATHS[@]}"; do
for size in "${ICON_SIZES[@]}"; do
path="${base_path/\*/$size}"
if [ -d "$path" ]; then
icon_path=$(find "$path" -name "*.png" -o -name "*.svg" 2>/dev/null | head -n 1)
if [ -n "$icon_path" ]; then
# 复制图标,使用应用程序名称作为文件名
cp "$icon_path" "$ICONS_DIR/$app_name.${icon_path##*.}"
icon_name="$app_name"
NEEDS_REFRESH=true
break 2
fi
fi
done
done
fi
# 创建桌面入口文件
log "正在创建桌面入口文件..."
cat >"$APPLICATIONS_DIR/$app_name.desktop" <<EOF
[Desktop Entry]
Name=$app_name
Exec="$appimage_path" %F
Icon=$icon_name
Terminal=false
Type=Application
Categories=$categories
Comment=$app_name Application
StartupWMClass=$wm_class
MimeType=application/x-executable;
EOF
# 设置执行权限
chmod +x "$appimage_path"
log "完成安装 $app_name"
return 0
}
# 主安装逻辑
if [ -d "$APPIMAGE_PATH" ]; then
# 如果是目录,则批量安装
log "正在扫描目录: $APPIMAGE_PATH"
find "$APPIMAGE_PATH" -maxdepth 1 -type f -name "*.AppImage" | while read -r appimage; do
install_appimage "$appimage"
done
else
# 如果是单个文件,则安装单个
install_appimage "$APPIMAGE_PATH"
fi
# 如果需要刷新,则延迟执行
if [ "$NEEDS_REFRESH" = true ]; then
log "将在 $REFRESH_DELAY 秒后更新桌面数据库..."
(
sleep "$REFRESH_DELAY"
update-desktop-database "$APPLICATIONS_DIR"
gtk-update-icon-cache -f -t "$ICONS_DIR"
log "桌面数据库更新完成"
) &
fi
log "所有操作完成!"
评论区