Instantly share code, notes, and snippets.
Last active
November 26, 2024 22:47
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save bonnebulle/0ed8f0b5e3022a486d5586007e4a859b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# GIST | |
# https://gist.github.com/bonnebulle/0ed8f0b5e3022a486d5586007e4a859b | |
# OBJECTIF | |
# Remove unused/dead menu entries in xfce/linux menu | |
# VARS | |
editor_modifications="codium" | |
install_commande_auto="yay -Syu --noconfirm --needed --overwrite \*" | |
install_commande_normal="yay -Syu --needed --overwrite \*" | |
install_commande_search="yay -Ss" | |
###################### | |
# TODO more paths | |
# /usr/share/applications/ | |
# ~/.local/share/applications/ | |
# PARAMETERS | |
# --v : Vérifier .desktop | |
# --vd : Vérifier .desktop (mode détaillé) | |
# --r : Si dead - Supprimer / install ( normal ) | |
# --ra : Si dead - Supprimer / install ( auto ) | |
# PROMPT options | |
# r : remove | |
# g : keep/garder | |
# x : ignore | |
# i : install | |
# a : alt install | |
# s : search (yay) | |
# p : prompt (yay direct name install) | |
# e : edit | |
################## | |
## SOURCES | |
# https://stackoverflow.com/a/677212 | |
# https://stackoverflow.com/a/20268787 | |
# + CLAUDE IA + Cursor | |
# https://claude.site/artifacts/71f24c0d-67e4-477e-bd54-86a37c800884 | |
# Fonction pour nettoyer et extraire la commande principale | |
clean_exec_command() { | |
local exec_line="$1" | |
# Supprimer "Exec=" s'il est présent | |
exec_line=$(echo "$exec_line" | sed -e 's/^Exec=//' | sed -e 's/^TryExec=//') | |
# Supprimer les options %U, %F, etc. | |
exec_line=$(echo "$exec_line" | sed -E 's/\s*%(f|F|u|U|d|D|n|N|i|c|k|v|m)//gi') | |
# Prendre le premier mot (la commande) | |
local first_cmd=$(echo "$exec_line" | awk '{print $1}') | |
# Résoudre les liens symboliques et les chemins absolus | |
if [[ "$first_cmd" == /* ]]; then | |
echo "$first_cmd" | |
else | |
echo "$first_cmd" 2>/dev/null | |
fi | |
} | |
# Fonction pour nettoyer et extraire la commande name | |
clean_exec_name() { | |
local exec_name="$1" | |
# Supprimer "Exec=" s'il est présent | |
exec_name=$(echo "$exec_name" | sed -e 's/^Name=//') | |
# Supprimer les options %U, %F, etc. | |
# exec_line=$(echo "$exec_line" | sed -E 's/\s*%(f|F|u|U|d|D|n|N|i|c|k|v|m)//gi') | |
# Prendre le premier mot (la commande) | |
local first_name=$(echo "$exec_name" | awk '{print $1}') | |
# TODO, Redo check | |
# Résoudre les liens symboliques et les chemins absolus | |
# if [[ "$first_cmd" == /* ]]; then | |
# echo "$first_cmd" | |
# else | |
# echo "$first_cmd" 2>/dev/null | |
# fi | |
echo $first_name | |
} | |
# Fonction pour tester si la commande est exécutable | |
test_exec_command() { | |
local cmd="$1" | |
# Vérifier si la commande existe dans le système | |
if command -v "$cmd" > /dev/null 2>&1; then | |
return 0 | |
fi | |
# SOURCE :: https://stackoverflow.com/a/677212 | |
if ! command -v $first_cmd 2>&1 >/dev/null | |
then | |
echo | |
echo | |
echo "----- $1 found" | |
return 0 | |
else | |
echo | |
echo | |
echo "----- $1 ( not found )" | |
return 1 | |
fi | |
} | |
# Fonction pour extraire le chemin d'exécution d'un fichier .desktop | |
extract_exec_path() { | |
grep -Ph '(?<=Exec=).*?( |$)' "$1" | head -n 1 | |
} | |
extract_exec_name() { | |
# TODO explicit ^Name=... dont catch OptName=... | |
grep -Ph '(?<=Name=).*?( |$)' "$1" | head -n 1 | |
} | |
# Fonction de suppression interactive | |
remove_desktop_file() { | |
local file="$1" | |
local exec_path="$2" | |
local sata="$3" | |
# SOURCE :: https://stackoverflow.com/a/20268787 | |
if sudo grep -q '^IGNORE_MENU' "$file"; then | |
echo IGNORE_MENU présent dans | |
echo "--- $file" | |
echo "--- $exec_path" | |
else | |
# echo "debug $sata" | |
# Vérifier si le mode détaillé est demandé | |
if [[ $sata == "auto" ]]; then | |
auto_install=true | |
fi | |
# echo "debug install $sata :" | |
if [ "$auto_install" = true ]; then | |
install_commande_option=$install_commande_auto | |
else | |
install_commande_option=$install_commande_normal | |
fi | |
# echo "debug $install_commande_option" | |
# sleep 11000 | |
# Vérifier si gio ou gvfs-trash est disponible | |
if command -v gio &> /dev/null; then | |
trash_cmd="gio trash" | |
elif command -v gvfs-trash &> /dev/null; then | |
trash_cmd="gvfs-trash" | |
else | |
echo "Erreur : Aucun outil de corbeille trouvé (gio ou gvfs-trash)" | |
return 1 | |
fi | |
first_cmd_new=$(echo "$exec_path" | awk '{print $1}') | |
first_cmd_fix=$(echo "$first_cmd_new" | sed -e 's/^Exec=//' | sed -e 's/^TryExec=//') | |
lastpath=${first_cmd_fix##*/} | |
# echo "lastpath == "$lastpath | |
# echo "clean_name == "$clean_name | |
# Prompt de confirmation avec informations détaillées | |
read -p "Fichier .desktop --- '$file' ( commande : $exec_path )`echo $'\n\n> '`==> (a) $clean_name `echo $'\n> '`==> (i) $lastpath `echo $'\n\n> '`... manquant, déplacer vers la corbeille ? `echo $'\n> '`-- (r)emove / (g)arder / (x)ignorer`echo $'\n>'` -- (i)nstall / (a)lt / (n)ormal`echo $'\n>'` -- (p)rompt / (s)earch / (e)dit ? " response | |
# Convertir la réponse en minuscules | |
response=$(echo "$response" | tr '[:upper:]' '[:lower:]') | |
if [[ "$response" == "r" || "$response" == "remove" ]]; then | |
# Utiliser sudo si nécessaire (fichiers système) | |
# TODO add ~/.local/share/applications/*.desktop ?? | |
if [[ "$file" == "/usr/share/applications/"* ]]; then | |
# Demander le mot de passe sudo | |
echo | |
echo "--- REMOVE" | |
echo "Ce fichier nécessite des permissions administratives." | |
if sudo -v; then | |
# Utiliser sudo pour déplacer le fichier | |
if sudo $trash_cmd "$file"; then | |
echo "Fichier '$file' déplacé dans la corbeille (avec permissions administratives)." | |
else | |
echo "Erreur lors du déplacement du fichier '$file' vers la corbeille." | |
return 1 | |
fi | |
else | |
echo "Authentification sudo échouée. Opération annulée." | |
return 1 | |
fi | |
else | |
# Fichiers utilisateur : pas besoin de sudo | |
if $trash_cmd "$file"; then | |
echo "Fichier '$file' déplacé dans la corbeille." | |
else | |
echo "Erreur lors du déplacement du fichier '$file' vers la corbeille." | |
return 1 | |
fi | |
fi | |
echo | |
echo | |
elif [[ "$response" == "i" || "$response" == "install" ]]; then | |
echo | |
echo "----- install" | |
mycmd=$lastpath | |
echo | |
echo "install ( mod $sata ) :" | |
echo $mycmd | |
echo | |
echo | |
sleep 2 | |
if [[ $($install_commande_search "$mycmd") ]] | |
then | |
$install_commande_option $mycmd | |
else | |
echo "--- INSTALLER DONT FOUND" | |
echo | |
remove_desktop_file "$1" "$2" "$3" | |
fi | |
elif [[ "$response" == "a" || "$response" == "alt" ]]; then | |
echo | |
echo "----- alt" | |
mycmd=$clean_name | |
echo | |
echo "install (alt)" | |
echo $mycmd | |
echo | |
sleep 2 | |
if [[ $($install_commande_search "$mycmd") ]] | |
then | |
$install_commande_option "$mycmd" | |
else | |
echo "--- INSTALLER DONT FOUND -- Re_DO " | |
echo | |
remove_desktop_file "$1" "$2" "$3" | |
fi | |
elif [[ "$response" == "n" || "$response" == "normal" ]]; then | |
echo | |
echo "----- normal" | |
mycmd=$clean_name | |
echo | |
echo "install (normal -- skip auto)" | |
echo $mycmd | |
echo | |
sleep 2 | |
if [[ $($install_commande_search "$mycmd") ]] | |
then | |
$install_commande_normal "$mycmd" | |
else | |
echo "--- INSTALLER DONT FOUND -- Re_DO " | |
echo | |
remove_desktop_file "$1" "$2" "$3" | |
fi | |
elif [[ "$response" == "e" || "$response" == "edit" ]]; then | |
echo | |
echo "EDIT $file" | |
$editor_modifications $file 2>&1 >/dev/null | |
echo | |
echo "--- BACK " | |
remove_desktop_file "$1" "$2" "$3" | |
elif [[ "$response" == "s" || "$response" == "search" ]]; then | |
read -p "-- search nom (prompt_name / n/s ) ? " sresponse | |
# sresponse=$(echo "sresponse" | tr '[:upper:]' '[:lower:]') | |
if [[ "$sresponse" != "n" && "$sresponse" != "no" && "$sresponse" != "s" ]]; then | |
echo | |
echo "----- search -- $sresponse" | |
echo | |
sleep 2 | |
echo "--- RESULTAT ---" | |
# $mycmd | |
$install_commande_search $sresponse | |
echo | |
echo "----------------" | |
fi | |
echo "--- INSTALLER DONT FOUND -- Re_DO " | |
echo | |
remove_desktop_file "$1" "$2" "$3" | |
elif [[ "$response" == "x" || "$response" == "ignore" ]]; then | |
echo | |
echo "----- ignore -> ajoute IGNORE_MENU" | |
echo "----- BYPASS NEXT TIME" | |
# mycmd="$response" | |
if sudo grep -q '^IGNORE_MENU' "$file"; then | |
sudo sed -i 's/^IGNORE_MENU.*/IGNORE_MENU=ok/' "$file" | |
else | |
echo 'IGNORE_MENU=ok' | sudo tee -a "$file" > /dev/null | |
fi | |
elif [[ "$response" == "p" || "$response" == "prompt" ]]; then | |
read -p "-- install autre nom (prompt_name / n/x ) ? " presponse | |
presponse=$(echo "$presponse" | tr '[:upper:]' '[:lower:]') | |
echo | |
echo "----- prompt" | |
mycmd="$presponse" | |
if [[ $($install_commande_search "$mycmd") ]] | |
then | |
$install_commande_normal "$mycmd" | |
else | |
echo "--- RIEN TROUVÉ" | |
echo "--- INSTALLER DONT FOUND -- Re_DO " | |
echo | |
remove_desktop_file "$1" "$2" "$3" | |
fi | |
else | |
echo "Suppression annulée pour '$file'." | |
fi | |
fi # IGNORE_MENU | |
} | |
# Fonction de vérification des exécutables | |
verify_desktop_files() { | |
local count=0 | |
local missing_count=0 | |
local detailed_output=false | |
# Vérifier si le mode détaillé est demandé | |
if [[ "$1" == "--d" ]]; then | |
detailed_output=true | |
fi | |
# Boucle de vérification des applications | |
for i in /usr/share/applications/*.desktop ~/.local/share/applications/*.desktop; do | |
# Vérifier si le fichier existe réellement | |
if [ -f "$i" ]; then | |
# Extraire le chemin d'exécution | |
exec_path=$(extract_exec_path "$i") | |
# Extraire le nom du fichier sans le chemin | |
filename=$(basename "$i") | |
# Nettoyer et extraire la commande | |
clean_cmd=$(clean_exec_command "$exec_path") | |
# Tester la commande | |
if ! test_exec_command "$clean_cmd"; then | |
echo -e "Fichier : $filename" | |
echo "Ligne Exec originale : $exec_path" | |
echo "Commande extraite : $clean_cmd" | |
# Incrémenter le compteur de commandes manquantes | |
((missing_count++)) | |
# Mode détaillé : afficher plus d'informations | |
if [ "$detailed_output" = true ]; then | |
echo "Détails supplémentaires :" | |
which "$clean_cmd" 2>&1 || echo "Aucune correspondance trouvée" | |
fi | |
fi | |
# Incrémenter le compteur total | |
((count++)) | |
fi | |
done | |
# Afficher le résultat final | |
echo -e "\nVérification terminée." | |
echo "Total des fichiers vérifiés : $count" | |
echo "Nombre de commandes manquantes : $missing_count" | |
} | |
forloop_r() { | |
# echo "debug forloop_r ===" | |
# echo "debug #1 $1" | |
for i in /usr/share/applications/*.desktop ~/.local/share/applications/*.desktop; do | |
if [ -f "$i" ]; then | |
# Extraire le chemin d'exécution | |
exec_path=$(extract_exec_path "$i") | |
# Extraire le nom du fichier sans le chemin | |
filename=$(basename "$i") | |
# Nettoyer et extraire la commande | |
clean_cmd=$(clean_exec_command "$exec_path") | |
# Nettoyer et extraire le nom | |
clean_name=$(extract_exec_name "$i" | sed -e 's/^Name=//' | tr '[:upper:]' '[:lower:]') | |
# Tester la commande | |
if ! test_exec_command "$clean_cmd"; then | |
remove_desktop_file "$i" "$exec_path" "$1" | |
fi | |
fi | |
done | |
} | |
# Fonction principale | |
main() { | |
case "$1" in | |
"--r") | |
# Mode suppression | |
# echo "debug r" | |
forloop_r "normal" | |
;; | |
"--ra") | |
# Mode suppression | |
# echo "debug ra" | |
forloop_r "auto" | |
;; | |
"--v") | |
# Mode vérification standard | |
verify_desktop_files | |
;; | |
"--vd") | |
# Mode vérification détaillé | |
verify_desktop_files --d | |
;; | |
*) | |
echo "Utilisation :" | |
echo | |
echo "--r : Si commande manquante`echo $'\n '` Supprimer / install ( norm )`echo $'\n '`" | |
echo "--ra : Si commande manquante`echo $'\n '` Supprimer / install ( auto )`echo $'\n '`" | |
echo "--v : Vérifier .desktop`echo $'\n '`" | |
echo "--vd : Vérifier .desktop (mode détaillé)" | |
echo | |
# Prompt de confirmation avec informations détaillées | |
read -p "r / ra / v / vd ? " responsea | |
# Convertir la réponse en minuscules | |
responsea=$(echo "$responsea" | tr '[:upper:]' '[:lower:]') | |
if [[ "$responsea" == "r" || "$responsea" == "ra" || "$responsea" == "rv" || "$responsea" == "vd" ]]; then | |
echo "GO --- " $responsea | |
echo "( wait )" | |
main "--$responsea" | |
else | |
echo "--wrong, exit" | |
exit 1 | |
fi | |
;; | |
esac | |
} | |
# Appeler la fonction principale avec les arguments | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment