#1 Le 08/06/2008, à 23:38
- Pandark
Gestion de la corbeille Nautilus par Bash
Bonjour, bonsoir ou bonne nuit ,
J'ai rédigé un script (en fait, une partie de mon .bashrc) pour envoyer des fichiers dans la corbeille de Nautilus au lieu de les supprimer directement lorsque j'utilise la fonction rm.
J'ai essayer de faire une mimique du comportement de Nautilus (même numérotation des homonymes, fichiers d'infos identiques...) et de rester proche des options de rm (-ivfr).
À priori, ça marche, tant qu'il n'y a ni espaces ni guillemets (simples ou doubles) dans les chemins et noms des fichiers...
Donc en gros, il faudrait corriger ce bug, et après ajouter une fonction de listage des fichiers de la corbeille et une de restauration de fichiers depuis la corbeille (certains essaient de le rajouter dans Nautilus).
Si vous avez une idée de comment corriger le bug existant ou si trouvez d'autres bugs...
alias rm='rm_to_trash'
function rm_to_trash()
(
#Fonction d'envoi dans la corbeille de Nautilus, par Pandark
opt=-T
trash_folder=~/.local/share/Trash
while getopts ":IiFfRrVv" OPTION
do
case $OPTION in
F|f) # option "-f"
opt+="f"
force="yes"
;;
r|r) # option "-r"
opt+="r"
;;
I|i) # option "-i"
interactive="yes"
;;
V|v) # option "-v"
verbose="yes"
;;
:) # pas d'option
;;
\?) # option incorrecte
echo -e "Option invalide\n"
echo "Usage : rm [option] [paramètre]"
echo "Options = -i (interactif) ou -f (forcé) ou -r (récursif) ou -v (bavard)"
echo "Suppression directe : \rm"
exit
;;
esac
done
shift $(($OPTIND - 1)) #On place le curseur après les options
for filename in "$@"
do
if [ -e "$filename" ]
then
filepath=`dirname "$filename"`; filepath=`readlink -f "$filepath"`
new_filename="$filepath/${filename##*/}"
if [ "$interactive" = "yes" -a "$force" != "yes" ]
then
PS3="Déplacer le fichier \`$filename' dans la corbeille ?" # le prompt/la question
select choix in "[y]es" "[n]o"; do
case $REPLY in
1|Y*|y*)
confirmed="yes"
break
;;
2|N*|n*)
confirmed="no"
break
;;
esac
done
fi
if [ "$confirmed" != "no" ]
then
if [ -e "$trash_folder/files/${new_filename##*/}" ] # Si un fichier du même nom existe dans la corbeille...
then
copie=2
new_filename="$filepath/${filename%%.*}.$copie.${filename#*.}"
while [ -e "$trash_folder/files/${new_filename##*/}" ] # Tant qu'un fichier du même nom existe dans la corbeille...
do
let "copie += 1"
new_filename="$filepath/${filename%%.*}.$copie.${filename#*.}"
done
fi
#TODO : gestion des espaces, guillemets simples et guillemets doubles
mv $opt "$filename" "$trash_folder/files/${new_filename##*/}"
echo -e "[Trash Info]\nPath=$filepath/${filename##*/}\nDeletionDate=`date +"%FT%T"`" > "$trash_folder/info/${new_filename##*/}.trashinfo"
if [ "$verbose" = "yes" ]; then echo -e "Le fichier $filename est déplacé dans la corbeille."; fi
fi
else
echo -e "$filename : Aucun fichier ou repertoire de ce type"
fi
done
)
Une autre fonction, juste pour vider la corbeille:
function empty_trash()
(
#Fonction pour vider la corbeille de Nautilus, par Pandark
trash_folder=~/.local/share/Trash
\rm $trash_folder/files/* $trash_folder/info/*
)
Dernière modification par Pandark (Le 09/06/2008, à 10:27)
Pandark
99% libre…
Hors ligne
#2 Le 09/06/2008, à 02:24
- yurek
Re : Gestion de la corbeille Nautilus par Bash
si tu pouvais expliquer ton code: je décroche a partir du while
http://doc.ubuntu-fr.org/installation/debutants
http://doc.ubuntu-fr.org/diagnostic
http://doc.ubuntu-fr.org/diagnostic_outils
http://doc.ubuntu-fr.org/reflexe_ubunteros
Hors ligne
#3 Le 09/06/2008, à 05:24
- Pandark
Re : Gestion de la corbeille Nautilus par Bash
Alors pour le getopts du début, un exemple bien expliqué sur HFR et
Des extraits du man
getopts chaîne_d_options nom [arguments]
Il place également l'index de l'argument suivant à analyser dans la variable OPTIND. OPTIND est initialisé à 1 à chaque lancement d'un shell ou d'un script.
[...]
Si le premier caractère de la chaîne_d_options est un deux-points, les erreurs sont renvoyées de manière silencieuse.
[...]
Si une option illégale est rencontrée, getopts met un point d'interrogation ? dans la variable nom, affiche un message d'erreur (s'il n'est pas en mode silencieux), et détruit la variable OPTARG. Si getopts fonctionne en mode silencieux, le caractère d'option est placé dans OPTARG et aucun message de diagnostique n'est affiché.
Don là ça devrait aller jusqu'au shift (le commentaire de cette ligne étant assez explicite)...
for filename in $@
do
if [ -e "$filename" ]
then
Pour tout fichier existant passé en argument
PS3="Déplacer le fichier \`$filename' dans la corbeille ?" # le prompt/la question
select choix in "[y]es" "[n]o"; do
case $REPLY in
1|Y*|y*)
confirmed="yes"
break
;;
2|N*|n*)
confirmed="no"
break
;;
esac
done
Là, ça me semble assez clair... il faut savoir que PS3 et $REPLY sont standards, donc ça va afficher les choix, puis la question et récupérer la réponse de l'utilisateur. Si ce n'est ni y... ni n..., ça va recommencer la boucle.
copie=2
new_filename="`dirname $filename`/${filename%%.*}.$copie.${filename#*.}"
Pour cette partie là, il faut savoir que Nautilus commence à numéroter à 2 le premier fichier pour lequel un fichier du même nom existe déjà dans la corbeille, et qu'il ajoute ce numéro après le premier point dans le nom du fichier (par exemple "mon.fichier.a.moi.txt" -> "mon.2.fichier.a.moi.txt" si c'est le deuxième fichier de ce nom supprimé)
Pour comprendre tous les ${filename%%.*}, ${filename#*.}, etc. ou `dirname $filename`, :
Avec ## (resp. #) on peut supprimer la plus longue (resp. courte) chaine correspondant au motif :
$ Nom=’Rep/toto.tar.gz’ $ echo ${Nom##*.} > gz $ echo ${Nom#*.} > tar.gz $ echo ${Nom##*t} > ar.gz $ echo ${Nom#*t} > oto.tar.gz
Pour faire la même chose avec la fin de la chaine, utilisez % (ou %%) :
$ echo ${Nom%.*} > Rep/toto.tar $ echo ${Nom%%.*} > Rep/toto $ echo ${Nom%%t*} > Rep/ $ echo ${Nom%t*} > Rep/toto.
Pis
dirname - strip non-directory suffix from file name
Pandark
99% libre…
Hors ligne
#4 Le 09/06/2008, à 06:08
- Alain.g
Re : Gestion de la corbeille Nautilus par Bash
Bonjour
Il faut placer les variables entre guillemets, exemple :
→ for i in "$@"
→ mv "$bidule"
http://abs.traduc.org/abs-5.3-fr/ch05.html#quotingvar
Pas seulement pour les espaces, mais aussi pour les autres caractères spéciaux :
f=*
rm "$f" # effacera uniquement le fichier se nommant *
rm $f # effacera tous les fichiers (sauf cachés et dossiers) du répertoire
Dernière modification par Alain.g (Le 09/06/2008, à 06:09)
Xubuntu Karmic !
Hors ligne
#5 Le 09/06/2008, à 10:26
- Pandark
Re : Gestion de la corbeille Nautilus par Bash
Ok, je crois que c'est mieux maintenant (je modifie dans le premier message)
Autre bug corrigé : le chemin inscrit dans le fichier info était relatif au lieu d'être absolu.
Pandark
99% libre…
Hors ligne
#6 Le 10/06/2008, à 01:16
- Pandark
Re : Gestion de la corbeille Nautilus par Bash
Voilà une fonction pour lister le contenu de la corbeille (avec date de suppression et emplacement d'origine)
Mais ça m'embête d'utiliser IFS=$'\n', donc si quelqu'un a une autre méthode...
D'ailleurs, est-ce que je dois sauvegarder la valeur de IFS et la remettre à la fin dans le cas présent, ou est-ce que ça reviendra tout seul à la valeur d'origine ?
function ls_trash()
(
#Fonction pour lister le contenu dee la corbeille de Nautilus, par Pandark
IFS=$'\n' # a cause des espaces du ls
trash_folder=~/.local/share/Trash
i=0
echo "fichier | nom original | date de suppression"
for residu in `ls "$trash_folder/files/"`
do
filename[$i]="$residu"
if [ -e "$trash_folder/info/${filename[$i]}.trashinfo" ]
then
truename[$i]="`sed -n "s/Path=\(.*\)/\1/p" "$trash_folder/info/${filename[$i]}.trashinfo"`"
deldate[$i]="` sed -n "s/DeletionDate=\(.*\)/\1/p" "$trash_folder/info/${filename[$i]}.trashinfo"`"
echo "${filename[$i]} | ${truename[$i]} | ${deldate[$i]}"
((i++))
fi
done
)
Dernière modification par Pandark (Le 10/06/2008, à 04:28)
Pandark
99% libre…
Hors ligne
#7 Le 10/06/2008, à 05:07
- Alain.g
Re : Gestion de la corbeille Nautilus par Bash
Bonjour
Une solution sans changer la valeur d'IFS :
à la place de
for residu in `ls "$trash_folder/files/"`
mettre
while read -r residu
et remplacer done par
done < <(ls "$trash_folder/files/")
On aurait pu également remplacer directement par :
ls "$trash_folder/files/" | while read -r residu
mais attention si la valeur des variables doit être conservée.
Les seuls espaces blancs qui devraient poser problème sont les sauts de ligne (très rare et déconseillé dans les noms de fichier).
Si on veut que ça fonctionne aussi avec les sauts de ligne, mettre :
while read -rd $'\0' residu
et
done < <(cd "$trash_folder/files/" ; find * -maxdepth 0 -print0)
Dernière modification par Alain.g (Le 10/06/2008, à 10:53)
Xubuntu Karmic !
Hors ligne