Demande conseils pour script effacement récursif de dossiers

Suite à mes essais de création de script à la fin de ce fil, j’ouvre cet autre fil en espérant obtenir des critiques et conseils.

Le but était de supprimer récursivement les dossiers vides en partant d’un dossier racine, et voila ce que j’ai fait:

[code]#!/bin/bash

En paramètre, le dossier de départ pour la recherche/suppression récursive des dossiers vides

find “$1” -type d -empty -print0 | xargs -r -0 rmdir
if [ $(find “$1” -type d -empty) ]; then
$0 "$1"
fi[/code]
Je ne doute pas qu’il doit y avoir beaucoup de défauts que je ne vois pas car je n’ai jamais eu de cours de programmation,
donc je n’y connais pas grand chose: j’ai juste bricolé de l’ASM sur 8088 et programmé des petites routines avec “debug du DOS 6.22” pour 8255, 8042, 8248, 8253, 16450, µPD765A, en gros, que du bas niveau, basé sur mes connaissances en électronique.

Tout conseil pour rendre plus propre ce script sera très apprécié.
Si vous pouviez me transmettre des liens que vous jugerez intéressants.

Merci d’avance.

ou
[code]find "$1" -depth -type d -empty -exec rmdir -p {} \;[/code]
devraient faire ce que tu cherche

ou

devraient faire ce que tu cherche

Le truc avec la mono ligne c’est que si un répertoire devient vide suite à une suppression précédente tu n’as pas l’assurance qu’il soit effacé lui aussi :017
Donc il est nécessaire d’utiliser une boucle “while” pour parfaitement épurer l’arborescence 8)

michel@local /tmp/tmp.dmap1ynoOe % mkdir -p a/b/c michel@local /tmp/tmp.dmap1ynoOe % du -a 0 ./a/b/c 0 ./a/b 0 ./a 0 . michel@local /tmp/tmp.dmap1ynoOe % find -depth -type d -empty -delete michel@local /tmp/tmp.dmap1ynoOe % du -a 0 .
:slightly_smiling:

Il en devient chiant ce Michel, il a toujours le dernier mot :unamused:
:laughing: :laughing: :laughing:
:023

Merci, beaucoup pour vos conseils, je vais me documenter sur ces options [strike]et refaire ce script en conséquence[/strike].
EDIT: en fait il n’y a même pas besoin de script car si le nom du dossier de départ est “aeffacer”, la ligne de commande find aeffacer/ -depth -type d -empty -delete suffit.
:slightly_smiling: Si tous les mecs “chiants” l’étaient de cette façon, ça serait le pied, alors vivent les mecs “chiants”. :slightly_smiling:

Ce qui n’empêche pas d efaire un script avec un seul mot à taper, au lieu de la ligne.

J’essaie :
proposition de nom pour ce script: rmemptydirs.sh (ou rmed.sh)

[code]#!/bin/bash

Pour supprimer les dossiers vides contenus dans un dossier

En paramètre, le dossier de départ pour la recherche/suppression récursive des dossiers vides

contenant=${1:-"$PWD"}
if [ -d “$contenant” ]; then
read -p "Pour confirmer votre demande de suppression des dossiers vides contenus dans le dossier “$contenant”, entrez “oui”: "
if [ “$REPLY” == “oui” ]; then
echo "$PWD effacement des dossiers de “$contenant” en cours …"
find “$contenant” -depth -type d -empty -delete
else echo "opération anullée."
fi
else
echo "===================================================================="
echo -e "Vous devez en paramètre un nom de DOSSIER contenant :\n"
echo -e "Exemple: $0 nom_du_dossier_contenant\n"
echo "===================================================================="
fi
[/code]

je suis en train de chercher comment utiliser les $OPTIONS (genre “-i”)pour demande de confirmation ou pas.

Moi, comme je suis fainéant, je ne mets pas d’extension, donc, “rmed”, que ke place dans /usr/local/bin.
Quand ce sont des scripts sans grand danger,je les “chown” root:adm et comme je suis dans le groupe adm, en règlant les bons droits, je peux exécuter.
Si c’est un script plus chaud, minimum de droits, root:root et, éventuellement une ouverture ‘sudo’.

Merci beaucoup pour ces conseils.

Il me faut d’abord lire et pratiquer un peu tout ça si je veux pouvoir poser des question pertinentes afin d’espérer avoir des réponses.
Si tu as d’autre liens à me transmettre, je suis preneur.

Merci encore.

Je suis aussi un fainéant, mais je crois que c’est de naissance, et même que j’ai pas du tout envie de changer à ce sujet.
Même si c’est des fois très fatiguant de chercher à en faire le moins possible, quel plaisir de voir son travail s’exécuter ensuite en ayant fournis un moindre effort.

Tu parle, je suis devenu golfeur. Quand j’ai besoin de plus d’une ligne pour faire quelque chose, j’ai tendance à penser que j’utilise le mauvais langage (à plus de 10 : j’utilise le mauvais langage…).

j’ai marqué ce fil comme résolu, car maintenant, je vais passer à une autre étape consistant à faire de ce script quelque chose d’acceptable dans le dossier “/usr/local/bin”.

AMHA, il manque encore :
Une fonction pour “parser” la ligne de commande et en extraire les options “-i” “-s” “–help” et peut-être plus…
Une fonction “usage” si option --help demandée ou paramètres manquants dans la ligne de commande d’appel.
Utiliser “which” pour vérifier si les commandes nécessaires (rmd et find … pour l’instant) au script sont accessibles (et dans quel dossier elles sont).
Vérifier les droits utilisateur pour les commandes et les dossiers à supprimer.
Une fonction pour afficher les dossiers effectivement supprimés (ou “à supprimer” si simulation demandée avec l’option “-s”) par le script.
Un garde fou pour éviter la suppression de dossiers vides mais indispensables au système.
Récupérer et traiter les codes d’erreur des programmes utilisés (find rmd).
Trouver quels sont les codes d’erreurs de sortie que ce script devrait renvoyer.

Et tout ce que je ne sais pas encore et que peut-être les programmeurs me conseilleront d’ajouter pour en faire quelque chose de “propre”.

Un grand MERCI à tous ceux qui m’ont aidé dans ce fil.

@ MisterFreez
Je bénéficie de l’AAH, alors pour le golf, vu que j’ai déjà un handicap, quoi-que, avec un script comme ça, j’étais plutôt très très mal PAR…tis, surtout que sur un green comme Linux, c’est plutôt la formule “stroke-play”, le “match play” c’est plutôt pour les windowziens et autres voleurs de fruits (pauvre Alan, s’il savait.).

[quote=“MisterFreez”]michel@local /tmp/tmp.dmap1ynoOe % mkdir -p a/b/c michel@local /tmp/tmp.dmap1ynoOe % du -a 0 ./a/b/c 0 ./a/b 0 ./a 0 . michel@local /tmp/tmp.dmap1ynoOe % find -depth -type d -empty -delete michel@local /tmp/tmp.dmap1ynoOe % du -a 0 .
:slightly_smiling:[/quote]
Bon ben j’ai rien dit :blush:
En tous cas j’aurais appris quelque chose aujourd’hui :mrgreen:

Une ébauche de script “rmedir” :
(POSIX et GNU)

[code]#!/bin/bash
##########################

ScriptName : rmedir (remove empty dirs)

##########################

var

##########################
scriptBaseName=$(basename $0)
##########################

help msg

##########################
if [[ $LANG = fr* ]]; then # if french LANG locale.

msg="\n “$scriptBaseName”
permet de supprimer récursivement les répertoires vides contenus dans le répertoire de départ.\n
\n
Syntaxe : $scriptBaseName OPTION [chemin du répertoire de départ]\n
\n
Note: Si aucun répertoire de départ n’est donné, le répertoire courant ("$PWD") sera utilisé.\n
\n
Options: \n
-h ou --help\t\t - Affiche ce fichier d’aide.\n
-v ou --verbose\t - Mode verbeux.\n
-i ou --interactive\t - Demande de confirmation pour chaque suppression de répertoire vide.\n"

else # all other languages => en.

msg="\n “$scriptBaseName”
recursively removes empty folders from the start path.\n
\n
Syntax : $scriptBaseName OPTION [START PATH]\n
\n
Note: If no start path is given, the current path ("$PWD") will be used.\n
\n
Options:\n
-h or --help\t\t - Displays this help file.\n
-v or --verbose\t - Verbose mode.\n
-i or --interactive\t - Ask for confirmation for each empty folder deletion.\n"
fi
##########################
if [ $# = 0 ]; then # No args. ?
echo -e $msg # Display help message when no args.
else
while [ “$1” ]
do
case $1 in
-h | --help)
echo -e $msg # Display help message.
exit
;;
-v | --verbose)
cmd_supress="-exec rmdir -v" # Verbose mode.
shift
;;
-i | --interactive)
cmd_supress="-ok rmdir" # Ask for confirm before deletion.
shift
;;
esac
shift # Next arg. => Start Path.
done
if [ “$cmd_supress” ]; then
find $1 -depth -type d -empty $cmd_supress {} ;
else
find $1 -depth -type d -empty -delete
fi
fi
##################################

END

##################################
[/code]
Merci à tous ceux qui voudront laisser leur commentaires.

Bonjour,

Commentaire n1: faut dormir la nuit! :laughing:

Sinon les options courtes se gerent avec getopts:

while getopts hvi opt
do
    case $opt in
    h)
        // traitement si h
        ;;
    v)
        // traitement si v
        ;;
    i)
        // traitement si v
        ;;
    ?)
        // traitement si pas d'option
        ;;
    esac
done

A noter cependant:
[ul]ne gere pas les options les longues (mais il y’a surement qlqch dans bash pour le faire[/ul]
[ul]pour gerer les options qui non compatible entre elle il faut faire un bout de code specifique, typiquement: "si option “a” je mets le flag “a”, si option b alors que j’ai le flag “a” =>erreur [/ul]

Getopts permet de gerer les parametres des options(il suffit de rajouter “:” devant la lettre)

while getopts :oh opt
do
    case $opt in
        o)
            // un parametre
            output="$OPTARG";
            ;;
        h)
            //
            ;;
    esac
done

Merci beaucoup pour ces conseils.
Je vais donc commencer par me documenter à fond sur les options de getopts du Bash.
C’est tout-à fait le genre de conseils et de commentaires que je recherche.
N’hésitez surtout pas, et n’ayez pas peur de me vexer, je suis tellement débutant que je suis prêt à tout entendre.

@ tous :
Ne vous inquiétez pas au sujet de la pertinence (très discutable) de ce script: c’est juste un prétexte pour apprendre à faire un script “propre”.

Encore un GRAND MERCI.

EDIT:
style POSIX => options introduites par un seul tiret ("-")
style GNU => options introduites avec double tiret ("–")

C’est un peu pour ça que j’avais abandonné l’idée d’utiliser “getops”, mais (comme vous me le faites remarquer) ce n’est pas la bonne méthode.
Je vais donc plutôt utiliser “getops”.

?? Je ne sais pas pourquoi je n’arrive pas à utiliser la variable “OPTARG”, elle est toujours vide. ??

==============
J’ai aussi le projet de créer un fichier “.po” pour la traduction du message d’aide, comme l’a si bien fait “getops” pour ses messages d’erreur.
Je ne l’ai jamais fait, aussi, il me faudra trouver des renseignements “frais” à ce sujet.
J’avais déjà suivit l’excellent travail fait avec “gettext” pour les traductions, mais ça fait trop longtemps, aussi, je vais devoir faire une mise à jour de ce que je savais à ce sujet.

C’est pas derrière plutôt ?
wiki.bash-hackers.org/howto/getopts_tutorial

Si, c’est derriere. (ma faute, ma tres grande faute, mais je suis pas un expert non plus! :blush: )

De plus le cas “?” est en fait utilise quand on utilise une option avec parametre sans mettre le parametre:

#/bin/bash
while getopts p: name
do
        case $name in
        p)
                echo "Param: ${OPTARG}"
                ;;
        ?)
                echo "aucun param..."
                ;;
        esac
done

donne a l’execution:

$ ./test.sh -p toto
Param: toto
$ ./test.sh -p
./test.sh: option requires an argument -- p
aucun param...

Enfin si getopts gere les options courtes, getopt gere les options longues (mais la je n’ai jamais utilise, donc je ne connais pas…

il me semble que getopts est compatible avec tous les shell alors que getopt non …

[quote=“GNU libc Using Getopt”]… The options argument is a string that specifies the option characters that are valid for this program.
An option character in this string can be followed by a colon (‘:’) to indicate that it takes a required argument.
If an option character is followed by two colons (‘::’), its argument is optional; this is a GNU extension. …[/quote]

==============
Getopts => POSIX
Getopt => GNU
Getopt Long Options => GNU

==============
Small getopts tutorial -> Using it -> A first example
":a" => “… disable the verbose error handling by preceeding the whole option string with a colon (:slight_smile: …”

==============
Je pense qu’il me faudra m’inspirer de cet “Example of Getopt”, et peut-être même de “Getopt Long Options”.