diff --git a/local/bin/verif-desktop.sh b/local/bin/verif-desktop.sh new file mode 100755 index 0000000..c8f80cf --- /dev/null +++ b/local/bin/verif-desktop.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# Audit des fichiers .desktop : chemins manquants, apps cachées, erreurs de syntaxe + +DIRS=( + "$HOME/.local/share/applications" + "/usr/share/applications" +) + +RED='\033[0;31m' +YEL='\033[0;33m' +GRN='\033[0;32m' +BLU='\033[0;34m' +RST='\033[0m' + +ok=0 +warn=0 +err=0 + +check_file() { + local f="$1" + local name + name=$(basename "$f") + local issues=() + local hints=() + + # Ignorer les fichiers qui ne sont pas des Application affichables + local type + type=$(grep -m1 "^Type=" "$f" 2>/dev/null | cut -d= -f2-) + [[ "$type" != "Application" ]] && return + + # Détecter si c'est un gestionnaire d'URL ou un fichier système (NoDisplay=true y est normal) + local is_url_handler=false + grep -q "^MimeType=.*x-scheme-handler" "$f" 2>/dev/null && is_url_handler=true + + local is_user_dir=false + [[ "$f" == "$HOME/.local/share/applications/"* ]] && is_user_dir=true + + # NoDisplay ou Hidden : signaler uniquement dans le dossier utilisateur et si pas gestionnaire d'URL + local nodisplay hidden + nodisplay=$(grep -m1 "^NoDisplay=" "$f" | cut -d= -f2-) + hidden=$(grep -m1 "^Hidden=" "$f" | cut -d= -f2-) + if [[ "$is_user_dir" == true && "$is_url_handler" == false ]]; then + [[ "$nodisplay" == "true" ]] && issues+=("caché (NoDisplay=true) — n'apparaît pas dans le menu") + [[ "$hidden" == "true" ]] && issues+=("caché (Hidden=true) — n'apparaît pas dans le menu") + fi + + # Exec : extraire le premier token (sans %F %u etc.) + local exec_line exec_bin + exec_line=$(grep -m1 "^Exec=" "$f" | cut -d= -f2-) + # Retirer les guillemets englobants éventuels et les arguments %x + exec_bin=$(echo "$exec_line" | awk '{print $1}' | tr -d '"' | sed 's/%[a-zA-Z]$//') + + if [[ -z "$exec_bin" ]]; then + issues+=("Exec manquant") + elif [[ "$exec_bin" == /* ]]; then + # Chemin absolu + if [[ ! -f "$exec_bin" ]]; then + issues+=("exécutable introuvable : $exec_bin") + elif [[ ! -x "$exec_bin" ]]; then + issues+=("exécutable non exécutable : $exec_bin") + fi + else + # Commande dans le PATH (ignorer les wrappers shell) + if [[ "$exec_bin" != "sh" && "$exec_bin" != "bash" && "$exec_bin" != "env" ]]; then + if ! command -v "$exec_bin" &>/dev/null; then + issues+=("commande introuvable dans PATH : $exec_bin") + fi + fi + fi + + # Icône (chemin absolu uniquement — les noms de thème sont difficiles à vérifier) + local icon + icon=$(grep -m1 "^Icon=" "$f" | cut -d= -f2-) + if [[ "$icon" == /* && ! -f "$icon" ]]; then + hints+=("icône introuvable : $icon") + fi + + # Validation syntaxique (desktop-file-validate) + if command -v desktop-file-validate &>/dev/null; then + local syntax_out + syntax_out=$(desktop-file-validate "$f" 2>&1 | grep -v "^$") + while IFS= read -r line; do + [[ -z "$line" ]] && continue + if echo "$line" | grep -q "error:"; then + issues+=("syntaxe : ${line#*error: }") + elif echo "$line" | grep -q "warning:"; then + hints+=("syntaxe : ${line#*warning: }") + fi + done <<< "$syntax_out" + fi + + # Affichage + local max_hints=3 + if [[ ${#issues[@]} -gt 0 ]]; then + echo -e "${RED}✗ $name${RST}" + for i in "${issues[@]}"; do + echo -e " ${RED}→ $i${RST}" + done + local shown=0 + for h in "${hints[@]}"; do + (( shown >= max_hints )) && { echo -e " ${YEL}~ … (${#hints[@]} avertissements au total)${RST}"; break; } + echo -e " ${YEL}~ $h${RST}" + (( shown++ )) + done + (( err++ )) + elif [[ ${#hints[@]} -gt 0 ]]; then + echo -e "${YEL}~ $name${RST}" + local shown=0 + for h in "${hints[@]}"; do + (( shown >= max_hints )) && { echo -e " ${YEL}~ … (${#hints[@]} avertissements au total)${RST}"; break; } + echo -e " ${YEL}~ $h${RST}" + (( shown++ )) + done + (( warn++ )) + else + echo -e "${GRN}✓ $name${RST}" + (( ok++ )) + fi +} + +for dir in "${DIRS[@]}"; do + [[ -d "$dir" ]] || continue + echo -e "\n${BLU}=== $dir ===${RST}" + while IFS= read -r -d '' f; do + check_file "$f" + done < <(find "$dir" -maxdepth 1 -name "*.desktop" -print0 | sort -z) +done + +echo "" +echo -e "Résultat : ${GRN}$ok OK${RST} ${YEL}$warn avertissements${RST} ${RED}$err erreurs${RST}" diff --git a/local/share/doc/scripts-bash/verif-desktop.1.md b/local/share/doc/scripts-bash/verif-desktop.1.md new file mode 100644 index 0000000..f3615b3 --- /dev/null +++ b/local/share/doc/scripts-bash/verif-desktop.1.md @@ -0,0 +1,64 @@ +--- +tags: + - scripts +nom: verif-desktop +description: Audit des fichiers .desktop — chemins manquants, apps cachées, erreurs de syntaxe +--- + +# NOM + +verif-desktop - Audit des fichiers .desktop de Linux Mint + +# SYNOPSIS + +verif-desktop + +# DESCRIPTION + +Vérifie l'ensemble des fichiers `.desktop` présents dans `~/.local/share/applications/` et `/usr/share/applications/`. + +Pour chaque fichier, le script contrôle : + +- **Exécutable manquant** : le chemin absolu dans `Exec=` n'existe pas sur le disque +- **Exécutable non exécutable** : le fichier existe mais n'a pas le bit `+x` +- **Commande introuvable** : la commande dans `Exec=` n'est pas dans le `$PATH` +- **App cachée** : `NoDisplay=true` ou `Hidden=true` dans le dossier utilisateur (l'app n'apparaît pas dans le menu) +- **Icône manquante** : `Icon=` pointe vers un chemin absolu inexistant +- **Erreurs de syntaxe** : signalées par `desktop-file-validate` (catégories invalides, clés dépréciées…) + +Les gestionnaires d'URL (`MimeType=x-scheme-handler/...`) et les fichiers système sont traités différemment : `NoDisplay=true` y est attendu et n'est pas signalé comme erreur. + +# COMPATIBILITÉ + +Linux Mint (Cinnamon). Nécessite `desktop-file-utils` pour la validation syntaxique : + +``` +sudo apt install desktop-file-utils +``` + +# EXEMPLES + +Lancer l'audit complet : + ``` + verif-desktop + ``` + +# CODES DE RETOUR + +- `✓` vert — fichier valide +- `~` jaune — avertissement non bloquant +- `✗` rouge — erreur : l'application ne fonctionnera pas ou n'apparaîtra pas dans le menu + +# VERSIONS + +-26.05.1 +: Version originale + +# AUTEURS + +Cédric Abonnel - \ + +# RAPPORT D'ERREURS + +Pour signaler des erreurs ou des problèmes : +https://git.abonnel.fr/cedricAbonnel/scripts-bash