Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 31/08/2015, à 11: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, à 18:06)

Hors ligne

#2 Le 31/08/2015, à 12: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, à 12: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, à 13: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, à 14: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, à 14: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, à 14:15)

Hors ligne

#7 Le 31/08/2015, à 16: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, à 16: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)

Hors ligne

#9 Le 31/08/2015, à 16: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, à 16:14)

Hors ligne

#10 Le 31/08/2015, à 16: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, à 16:20)

Hors ligne

#11 Le 31/08/2015, à 16: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)

Hors ligne

#12 Le 31/08/2015, à 16:21

gormson

Re : [RESOLU] Problème : Noms de fichiers avec caractères à Echapper

WHAAAAAAAT

So merci de prendre le temps avec moi smile smile

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, à 16: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, à 16: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).

Hors ligne

#15 Le 31/08/2015, à 16: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, à 16:56)

Hors ligne

#16 Le 31/08/2015, à 17: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...

Hors ligne

#17 Le 31/08/2015, à 18: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