Page 1 sur 1

[Shell] - Petit problème bash

Posté : jeu. 13 janv. 2022 17:05
par tristan
Salut ici.

Je m'entraine à faire des script bash sur mon raspberry, mais je doit dire que je suis un peu déstabilisé par la syntaxe parfois un peu étrange.

J'était entrain de créé une sorte de mini script de sauvegarde qui clone l'installation système du pi dans une image qu'on peu flasher sur une carte.
Le script doit créé l'image et l'enregistrer dans un disque dure externe. Une fois ça fait, il parcour la liste des images enregistré dans le dossier de sauvegarde et supprime toute celles qui ont plus d'un mois.

presque tout fonctionne.
J'ai juste un problème, au moment de la suppression. J'utilise une condition qui est vraie quand la chaine de caractère passé en paramètre est bien un fichier.

ceci étant dit,, pour pouvoir poster mon script sur framboise314 et pour pouvoir le rendre plus adaptable j'ai coupé en deux le chemin du fichier, une première partie dans une variable apelé pathto correspond au chemin du dossier de sauvegarde, et la seconde partie FLTLF (file to lookfor) correspond au nom du fichier.
Hors, quand la comande rm s'exécute, elle se limite à pathto.
Même si j'ai combiné les deux variable avant de les passer à la comande pour éviter tout problème de concaténation pendant l'exécution.
j'ai essayé plusieurs bricoles, je suis sur que c'est un truc très con et que c'est juste moi qui ne tilte pas la de suite... enfin si quelqu'un avait réponse à cette question...


du coup voici le code:

Code : Tout sélectionner

	while [ $a_year[$loopind+2] != $monthof ]
	do
		#fl file t to lf look for
		fltfl="sauvegarde de ${a_year[$loopind]} ${yearof}.img"
		if [ -e "$pathto$fltlf" ]
		then
			cvlc /home/pilot/bin/saver/oldest_targeted.ogg
			rm "$pathto$fltlf"
			cvlc /home/pilot/bin/saver/oldest_destroyed.ogg
		fi
		
		#on ajoute 1 à loopind pour parcourir le tableau des mois
		loopind=$loopind+1
echo "$pathto$fltlf"	
done
fi

Re: Petit problème bash

Posté : jeu. 13 janv. 2022 18:08
par domi
Bonjour,
si je comprend bien ton besoin, tu cherches à supprimer les fichiers d'un dossier, dont leur date est supérieur à 1 mois ?

Dans ce cas, pourquoi ne pas simplement utiliser la commande :

Code : Tout sélectionner

find /path/to/files -mtime +30 -exec /bin/rm {} \;
find va lister tous les fichiers dans "/path/to/files" datant de plus de 30 jours, pour ensuite exécuter un commande "rm" uniquement sur ces fichiers. Il tient compte de la date de modification du fichier, on peut le remplacer par "ctime" pour calculer sur la date de création.
Pour tester la commande tu peux en lançant la commande dans une console retourner le résultat dans un "ls" afin de vérifier que cela est bien ce que tu attends.

Code : Tout sélectionner

find /path/to/files -mtime +30 -ls
Cela doit retourner la liste des fichiers que tu souhaites effacer.

PS : Je déplace ce sujet de la rubrique "débutant" vers la rubrique "Autre language".

Re: [Shell] - Petit problème bash

Posté : jeu. 13 janv. 2022 21:09
par Artemus24
Salut à tous.

J'ai trouvé la solution ! Voici ce que tu as écrit :

Code : Tout sélectionner

fltfl="sauvegarde de ${a_year[$loopind]} ${yearof}.img"
if [ -e "$pathto$fltlf" ]
Tu n'as pas exactement la même variable.
A la première ligne, elle s'écrit : "fltfl".
Tandis qu'à la seconde ligne, elle s'écrit : "flglf".
Tu as inversé les deux dernières caractères de ta variable.

Cordialement.
Artemus24.
@+

Re: [Shell] - Petit problème bash

Posté : jeu. 13 janv. 2022 22:07
par piper
Et pour terminer l'explication saches que en shell,
lorsque tu utilises une variable, c'est comme si à l'exécution, elle était remplacée par sa valeur avant exécution du script (je sais c'est bizarre) du coup si tu fais ceci
if [ "$a" == "3" ]; then
Cela devient if [ "" == "3" ]; then ce qui est syntaxiquement correct

Mais si tu fais
if [ $a == "3" ]; then
Cela devient if [ == "3" ]; then ce qui est syntaxiquement incorrect et le script plante.

D'où la bonne idée de protéger tes valeurs par des doubles quotes comme tu l'as fait (ou par l'utilisation d'accolades comme ${a}
Certains préfères faire avant if [ -n $a ]; pour savoir si la chaine $a a une longueur >0 ou pas

En corolaire, lorsque tu appelles une variable qui n'est pas renseignée et que la syntaxe reste correcte malgré tout , le script tourne sans erreur
mais c'est comme si elle valait une chaîne vide

Autrement dit si tu fais :
dir="/tmp/"
fichier="toto.txt"
Alors "$dir""$fic" devient /tmp/ parce que fic n'est pas déclarée et est donc considérée comme vide.

Et c'est ce qui s'est passé dans ton cas.
N'hésites pas au début à mettre des echo et des exit dans ton script quand tu tombes sur un loup pour débugger.
Tu peux faire
..............
.................
echo "$blabla" << affiche la valeur de la variable qui te turlupines
exit 0 << arrête l'exécution ici (pour ne pas que le script se poursuive)
..............

Tout le monde s'est déjà fait avoir et on se fait encore avoir régulièrement...... moi aussi.
Attention à ce que cela ne finisse pas en rm -rf /..... surtout si le script est lancé en avec sudo :shock: :shock: :shock: :shock: :shock: :shock: