Bonjour, je suis en train de faire du ménage sur mon mac (mais ça pourrait très bien être une machine sous linux).
Notamment, après avoir écrit des scripts qui suppriment ou déplacent des fichiers, je voudrais supprimer les répertoires qui sont "réellement vides" ou "quasiment vides".

Un répertoire réellement vide est un répertoire ne contenant aucun fichier ou dossier visible, ni aucun fichier ou dossier invisible (exception faite de "." et "..", bien sûr) et peut donc être supprimé par la commande rmdir.

Pour moi, un répertoire quasiment vide est un répertoire ne contenant rien d'autre qu'un fichier "quasiment inutile", comme .DS_Store (sous OS X).

Attention: un répertoire ne contenant qu'un sous-répertoire comme .git, par exemple, n'est PAS considéré comme quasiment vide !

Attention: je ne souhaite pas supprimer tous les fichiers .DS_Store (dont certains peuvent être utiles...)

En cherchant sur internet, j'ai trouvé une solution à base de ls:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
function dir_ls_empty_p() {
    local files
    files=$(ls -A "$1" | head -2) # pour éviter de générer une trop grande chaine s il y a plein de fichiers
    if test -z "$files"; then return 0; fi
    if test "$files" = ".DS_Store"; then return 0; fi
    return 1
}
que l'on peut "raccourcir" en:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
function dir_ls_empty_p() {
    local files
    files=$(ls -A "$1" | head -2)
    test -z "$files" && return 0
    test "$files" = ".DS_Store"
}
mais, bien sûr, N_BaH va probablement dire que ça ne marche pas si un petit malin s'amuse à créer un unique fichier comme .DS_Store\n (mais qui aurait une idée pareille ?):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
mkdir "./empty-not-DS-ret"
touch 'empty-not-DS-ret/.DS_Store    
'
dir_ls_empty_p "./empty-not-DS-ret" && echo '=> vide'
=> vide
ou si on crée un fichier "return":
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
mkdir "./empty-not-ret"
touch 'empty-not-ret/    
'
dir_ls_empty_p "./empty-not-ret" && echo '=> vide'
=> vide

J'ai aussi trouvé une solution à base de find:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
function dir_is_empty_p() {
    local files
    files=$(find "$1" -name '.DS_Store' -prune -o -mindepth 1 -maxdepth 1 -print -quit)
    if test -z "$files"; then return 0; fi
    return 1
}
que l'on peut "raccourcir" en:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
function dir_is_empty_p() {
    local files
    files=$(find "$1" -name '.DS_Store' -prune -o -mindepth 1 -maxdepth 1 -print -quit)
    test -z "$files"
}
et qui semble plus robuste, notamment pour les fichiers avec "return".

J'ai quelques questions:
  1. Voyez-vous des bugs (cas mal traités) dans cette fonction ?
  2. Voyez-vous d'autres solutions ? (si possible compatibles avec zsh)
  3. Comment "étendre" cette fonction (ou une autre) pour une liste de noms de fichiers "inutiles" (soit dans une variable, soit dans un fichier) ?