#1 Le 31/08/2015, à 10:39
- gormson
[RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Bonjour,
Je suis face à un petit soucis.
Je doit traiter des fichiers via un script. Ce script reçoit en paramètre le chemin complet du fichier mais comme une chaine de caractère.
Dison que mon Script s'appelle MonScript.sh, ça va donner ça
./test.sh "/home/user/dossier1/SousDossier/[blabla]blublu ABC (encore du texte).ext"
j'ai donc la possibilité d'avoir en vrac dans la chaine de caractère : des espaces, des crochets, des parenthèses bref tout un tas de chose qui vont foutre le bazar dans mon script par la suite.
En cherchant un peut j'ai trouvé cet example pour formater correctement ma chaine de caractères avec les caractères d'échappement.
echo "file"with"quotes( and 'simple').ex" | sed 's/\([\() '\''"]\)/\\\1/g'
Quand je l'utilise dans le shell avec mes fichiers non traités ça fonctionne correctement mais impossible de l'utiliser dans mon script.
J'ai essayé ça :
#!/bin/bash
CHEMINFICHIER=$1
CHEMINFICHIER=${echo '$CHEMINFICHIER' | sed 's/\([\() '\''"]\)/\\\1/g'}
echo "Chemin Propre $CHEMINFICHIER"
mais j'ai ce message d'erreur
./MonScript.sh: ligne5: ${echo '$CHEMINFICHIER' | sed 's/\([\() '\''"]\)/\\\1/g'} : mauvaise substitution
du coup je ne sais plus du tout quoi faire :
-- j'ai essayé de passer par un eval sans succès
-- j'ai essayé d'insérer des caractères d'échappement pareil ça merde....
Comme je ne m'y connais pas assez pour savoir ce que je fais de mal je me tourne vers vous...
si une âme charitable pouvait m'aider se serait génial....
Merci d'avance.
Dernière modification par gormson (Le 31/08/2015, à 17:06)
Hors ligne
#2 Le 31/08/2015, à 11:06
- pingouinux
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Bonjour,
Inutile de te casser la tête. Tu appelles ton script comme tu l'as fait
./test.sh "/home/user/dossier1/SousDossier/[blabla]blublu ABC (encore du texte).ext"
et dans le script
CHEMINFICHIER="$1"
echo "Chemin Propre $CHEMINFICHIER"
(toujours mettre des " " quand tu utilises la variable : "$CHEMINFICHIER")
Hors ligne
#3 Le 31/08/2015, à 11:21
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Bonjour,
Merci pour la réponse. Le fait est qu'ensuite j'ai des traitements à faire le fichier du coup je pense que j'ai besoin du nom avec les caractères d'échappement non?
Quel est l'impact de mettre des guillemets autour de $1?
Hors ligne
#4 Le 31/08/2015, à 12:27
- pingouinux
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Le fait est qu'ensuite j'ai des traitements à faire le fichier du coup je pense que j'ai besoin du nom avec les caractères d'échappement non?
Si ça ne marche pas comme tu veux, merci de donner un exemple précis.
Quel est l'impact de mettre des guillemets autour de $1?
Pour l'affectation de variable (CHEMINFICHIER="$1"), ça ne change rien, mais ça ne mange pas de pain (j'ai l'habitude de les mettre systématiquement).
echo $1 # Ne sera pas correct si la variable contient des espaces consécutives
Les guillemets permettent de traiter la variable comme un tout, et nom comme une succession de champs séparés par des espaces.
Hors ligne
#5 Le 31/08/2015, à 13:04
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Merci pour les réponses,
Alors ce que j'essaye de faire :
j'ai des fichiers vers lesquels pointent des Hardlinks, du coup lorsque je veux supprimer ces fichiers, je veux les supprimer via leurs inodes.
Le truc c'est que le nom des fichiers contient parfois des caractères à échapper.
En utilisant ta méthode j'ai réussi à converger vers une meilleur utilisation des variable, tout semble fonctionner sauf la fin.
ça a donc résolu pas mal de mes problèmes mais ça a tout reporté sur la fin lorsque je lance la commande Find -exec rm
Comme j'utilise :
find /home/ -inum $INODE -exec rm {} \;
malgré le fait d'avoir réussi à récupérer l'inode du fichier avec des espaces toussa... et bien la commande find, elle, renvoie de nouveau une version avec espace qui n'est pas correctement interprété par rm... sorcellerie!!
j'ai essayé ça
COMMANDE="find /home/ -inum $INODE -exec rm \"{}\" \\;"
eval $COMMANDE
mais ça plante...
je suis au bord de la rupture lol
j'en suis venu à ce script :
#!/bin/bash
CHEMIN="$1"
UTILISATEUR="gormson"
#Recuperation de l'inode du CHEMIN à supprimer
#Traitement différent dans le cas d'un dossier
if [ -d "$CHEMIN" ]
then
#Ecriture de l'ensemble du contenu du dossier dans un fichier tampon
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "Traitement Dossier $CHEMIN" >> /home/$UTILISATEUR/.session/inode.log
#Creation d'une variable commande
COMMANDE="ls \"$CHEMIN\""
eval $COMMANDE >> /home/$UTILISATEUR/.session/inodedossier.log
#Lecture de chaque nom de fichier et traitement
while read -r ENCOURS; do
echo "Traitement fichier $ENCOURS" >> /home/$UTILISATEUR/.session/inode.log
COMMANDE="ls -i \"$CHEMIN\"/\"$ENCOURS\" | sed -e \"s|$CHEMIN/$ENCOURS||\""
INODE=$(eval $COMMANDE)
#Sauvegarde de l'inode et du nom du fichier correspondant dans un log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "Suppression inode $INODE | fichier $ENCOURS" >> /home/$UTILISATEUR/.session/inode.log
#Suppresion de tous les fichiers associes
find /home/ -inum $INODE -exec rm {} \;
#Verification de la bonne suppression des fichiers
find /home/ -inum $INODE >> /home/$UTILISATEUR/.session/inodefailed.log
done < /home/$UTILISATEUR/.session/inodedossier.log
rm -f /home/$UTILISATEUR/.session/inodedossier.log
COMMANDE="ls -id \"$CHEMIN\" | sed -e \"s|$CHEMIN ||\""
INODE=$(eval $COMMANDE)
echo "Suppresion du Dossier $CHEMIN" >> /home/$UTILISATEUR/.session/inode.log
echo "Suppression inode $INODE | fichier $CHEMIN" >> /home/$UTILISATEUR/.session/inode.log
find /home/ -inum $INODE -exec rm -R {} \;
#Verification de la bonne suppression des fichiers
find /home/ -inum $INODE >> /home/$UTILISATEUR/.session/inodefailed.log
else
echo "Traitement Mode Fichier"
COMMANDE="ls -i \"$CHEMIN\" | sed -e \"s|$CHEMIN ||\""
INODE=$(eval $COMMANDE)
#Sauvegarde de l'inode et du nom du fichier correspondant dans un log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "Suppression inode $INODE | fichier $TORRENTPATH" >> /home/$UTILISATEUR/.session/inode.log
COMMANDE="find /home/ -inum $INODE -exec rm \"{}\" \\;"
eval $COMMANDE
#Verification de la bonne suppression des fichiers
find /home/ -inum $INODE >> /home/$UTILISATEUR/.session/inodefailed.log
fi
Hors ligne
#6 Le 31/08/2015, à 13:14
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Salut,
1/ as-tu essayé tout simplement avec les guillements (non échappés) dans la commande find ?
find /home/ -inum $INODE -exec rm "{}" \;
2/ si ça ne marche pas, as-tu essayé avec xargs ?
find /home/ -inum $INODE | xargs rm
Dernière modification par tiramiseb (Le 31/08/2015, à 13:15)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#7 Le 31/08/2015, à 15:01
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
pour la commande find j'ai échappé les guillemets parce que je passe par un "eval" du coup la commande find est dans une chaine de caractère.
Pour essayer à la fois les deux solution (exec et xargs) voilà le cheminement :
Voilà la partie de code qui va être utilisée dans le cas :
COMMANDE="ls -i \"$CHEMIN\" | sed -e \"s|$CHEMIN ||\""
INODE=$(eval $COMMANDE)
#Sauvegarde de l'inode et du nom du fichier correspondant dans un log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "Suppression inode $INODE | fichier $CHEMIN" >> /home/$UTILISATEUR/.session/inode.log
find /home/ -inum $INODE | xargs rm
#Verification de la bonne suppression des fichiers
find /home/ -inum $INODE >> /home/$UTILISATEUR/.session/inodefailed.log
J'ai créé un dossier et un fichier exprès :
/home/gormson# ls \[machin-chose\]blabla\ blubu\ 420\ \(1280x720\)/
[machin-chose]blabla blubu 420 (1280x720).ext
je lance mon script :
/home/gormson# ./MonScript.sh "/home/gormson/[machin-chose]blabla blubu 420 (1280x720)/[machin-chose]blabla blubu 420 (1280x720).ext"
et voilà le résultat
Traitement Mode Fichier
sed: -e expression n°1, caractère 105: Fin d'intervalle invalide
find: Paramètre manquant pour « -inum »
rm: opérande manquant
Saisissez « rm --help » pour plus d'informations.
find: Paramètre manquant pour « -inum »
et maintenant avec exec
Le code quasi identique
COMMANDE="ls -i \"$CHEMIN\" | sed -e \"s|$CHEMIN ||\""
INODE=$(eval $COMMANDE)
#Sauvegarde de l'inode et du nom du fichier correspondant dans un log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "-------------------------------------------------------------------" >> /home/$UTILISATEUR/.session/inode.log
echo "Suppression inode $INODE | fichier $CHEMIN" >> /home/$UTILISATEUR/.session/inode.log
COMMANDE="find /home/ -inum $INODE -exec rm \"{}\" \\;"
eval $COMMANDE
#Verification de la bonne suppression des fichiers
find /home/ -inum $INODE >> /home/$UTILISATEUR/.session/inodefailed.log
et le résultat
Traitement Mode Fichier
sed: -e expression n°1, caractère 105: Fin d'intervalle invalide
find: Paramètre non valide « rm » pour « -inum »
find: Paramètre manquant pour « -inum »
Du coup n'y a t'il pas un moyen de remplacer tous les caractères à échapper par leur version avec échappement?
en utilisant Sed??
Hors ligne
#8 Le 31/08/2015, à 15:07
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Je ne comprends vraiment pas pourquoi tu mets des commandes dans des chaînes...
INODE=$(eval $COMMANDE)
Ici, qu'est-ce qui t'empêcherait de faire :
INODE=$(ls -i "$CHEMIN" | sed -e "s|$CHEMIN||")
?
... cela étant dit, ça ne fonctionne pas à cause de ce sed, ça n'a rien à voir avec la commande find.
Dans ton chemin, il y a des crochets, des parenthèses, ça gêne sed.
De toute manière, pourquoi utiliser sed ?
==>
INODE=$(ls -i "$CHEMIN" | cut -d" " -f1)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#9 Le 31/08/2015, à 15:12
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Voici un équivalent "propre" et probablement fonctionnel (pas testé) à ton script (j'ai cependant enlevé tous les trucs de logs, debug, tout ça) :
#!/bin/sh
CHEMIN="$1"
if [ -d "$CHEMIN" ]
then
for fichier in "$CHEMIN"
do
"$0" "$fichier"
done
elif [ -f "$CHEMIN" ]
then
find /home/ -inum $(ls -i "$CHEMIN" | cut -d" " -f1) -exec rm "{}" \;
fi
Dernière modification par tiramiseb (Le 31/08/2015, à 15:14)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#10 Le 31/08/2015, à 15:17
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Ah mince, j'avais même pas percuté. Y'a plus court.
Quand tu fais "ls -i" sur un répertoire, ça donne les i-nœuds de son contenu, du coup on peut directement bosser sur le retour de la commande "ls" exécutée sur le répertoire. Donc :
#!/bin/sh
for inode in $(ls -i "$1" | cut -d" " -f1)
do
find /home/ -inum $inode -exec rm "{}" \;
done
Bien sûr, ce n'est pas récursif, tout comme ton code d'origine : si un répertoire contient un répertoire, alors ça ne marche pas. Par contre, la proposition juste au-dessus est récursive.
Dernière modification par tiramiseb (Le 31/08/2015, à 15:20)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#11 Le 31/08/2015, à 15:19
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
(et, vraiment, il faut que tu arrêtes avec ta lubie des "eval". je ne sais pas d'où ça te vient, mais c'est parfaitement inutile et ça complexifie énormément ton machin)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#12 Le 31/08/2015, à 15:21
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
WHAAAAAAAT
So merci de prendre le temps avec moi
pitain c'est redoutable
en fait tu relance le script pour les fichiers du dossier c'est ça??
Hors ligne
#13 Le 31/08/2015, à 15:22
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
pour le eval désolé comme c'était la seule chose qui avait fonctionné jusque là me suis entêté ^^
j'essaye ton code et je reviens dire ce qu'il en est ^^
encore mercier
Hors ligne
#14 Le 31/08/2015, à 15:23
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
en fait tu relance le script pour les fichiers du dossier c'est ça??
C'est effectivement ce qu'il se passe avec la proposition en #9.
En #10 par contre, c'est plus simple (mais pas récursif).
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#15 Le 31/08/2015, à 15:56
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
Alors j'ai utilisé la version du #10
j'ai juste modifié le code à la fin pour effacer le dossier (si s'en est un)
ça donne ça
#!/bin/bash
UTILISATEUR="gormson"
for inode in $(ls -i "$1" | cut -d" " -f1)
do
echo "Traitement Inode $inode | Fichier $(find /home/ -inum $inode)"
find /home/ -inum $inode -exec rm "{}" \;
done
if [ -d "$1" ]
then
echo "Traitement Dossier $1"
find /home/ -inum $(ls -id "$1" | cut -d" " -f1) -exec rm -R "{}" \;
fi
le fichier dans le dossier est bien supprimé
le dossier est bien supprimé
mais j'ai ce message lors de l'execution
find: "/home/gormson/[machin-chose]blabla blubu 420 (1280x720)": Aucun fichier ou dossier de ce type
Du coup je ne comprends pas pourquoi il est effacé mais une erreur survient toujours :S
Dernière modification par gormson (Le 31/08/2015, à 15:56)
Hors ligne
#16 Le 31/08/2015, à 16:55
- tiramiseb
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
j'ai juste modifié le code à la fin pour effacer le dossier (si s'en est un)
Houla, encore une fois tu te compliques la vie pour rien.
find /home/ -inum $(ls -id "$1" | cut -d" " -f1) -exec rm -R "{}" \;
Tu recherches le nom du répertoire correspondant à l'inode du répertoire dont tu connais le nom.
... tu connais déjà le nom du répertoire :
#!/bin/sh
for inode in $(ls -i "$1" | cut -d" " -f1)
do
echo "Traitement Inode $inode | Fichier $(find /home/ -inum $inode)"
find /home/ -inum $inode -exec rm "{}" \;
done
if [ -d "$1" ]
then
rmdir "$1"
fi
Ensuite, deux choses :
1/ la variable $UTILISATEUR n'est pas utilisée, pas besoin de la définir
2/ il vaut mieux utiliser /bin/sh et non /bin/bash tant que tu n'utilises que des trucs POSIX, histoire d'être + interopérable
Concernant le message d'erreur à la fin, je ne vois pas non plus d'où ça vient.
Exécute avec "sh -x", déjà, pour voir quel "find" fait cette erreur...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#17 Le 31/08/2015, à 17:05
- gormson
Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper
A ben oui chuis tellement dans le rush que je fais pas gaffe...
j'ai modifié comme tu as dis, y compris pour le /bin/sh.
J'ai conservé ma variable en revanche car le script et a utiliser pour différent user qui auront tous leur log indépendant
En tout cas, merci pour ton aide si précise
tout fonctionne au poil
Merci de ta patience.
Hors ligne