#1 Le 14/08/2021, à 22:04
- philoeil
[ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Bonjour,
J'ai un script qui a généré lors d'une erreur d'exécution (aujourd'hui corrigée) un nom de fichier bizarre
Ce nom à fait planter mon script lors d'une exécution suivante sur le traitement de ce dossier à la forme de nom inhabituelle
J'aimerai ajouter un contrôle de routine (if then ou autre) qui évite ce plantage, soit en ne traitant pas ce fichier soit en traitant correctement ce nom de dossier. Pouvez-vous m'aider à formuler ce contrôle ?
La portion du script qui plante avec ce nom :
LaDATE='/bin/date'
BEFORE=$("$LaDATE" +'%s')
echo "$BEFORE"
TailleTotale=$(du -c "$REPCRD" | sed -n '/total/ s/[[:space:]].*//p')
echo '$TailleTotale :'"$TailleTotale" | tee -a "$CheminJournal"
TailleOK=0
# La ligne suivante affiche dans la variable tableau Fichiers les différents champs avec un séparateur=@ entre chemin et nom fichier et un séparateur espace entre les autres infos utilise \0 pour caractere de fin de ligne
# avec -t ajoute également silencieusement une nouvelle ligne finale manquante si le flux d'entrée n'en a pas
# l' option -d pour fournir un délimiteur de ligne différent.
mapfile -d '' -t Fichiers < <(find "$REPCRD" -not -path '*/\.*' -type f -size +"$TailleMo"M -printf "%h@%f@%s*%c* dernier accès le %AA %Ad %AB %AY à %AH:%AM:%AS*\0")
for Fichier in "${Fichiers[@]}"
do
# ${paramètre%%mot} suppression d'un motif correspondant au suffixe (ici mot= @*) Sur un tableau, tous ses éléments sont transformés
# %enlève le plus court motif, et %% le plus long
h="${Fichier%%@*}"
# echo "\$h=$h"
f="${Fichier%@*}"
# ${paramètre##mot} suppression d'un motif correspondant au préfixe (ici mot=*@) Sur un tableau, tous ses éléments sont transformés
# enlève le plus court motif,
f="${f#*@}"
# et ## enlève le plus long
# echo "\$f=$f"
reste="${Fichier##*@}"
Taille=$(du "${h}/${f}" | sed 's/[[:space:]].*//')
TailleOK=$((TailleOK + Taille))
echo -en "\rProgression : ${TailleOK} / ${TailleTotale}"
result=$(/usr/bin/md5sum -b "${h}/${f}")
result2=$(echo "$result" | cut -d '*' -f 1)
echo "$h*$f*${reste}$result2" | sort -n -t "*" -k 6| awk -F"*" '{ TMo=$3/1048576; printf $1" § "$2 " § " TMo " § " $4 " § " $5 " § " $6 "\n"; }' >> "$CheminActionDbl/$FILE2"
done
La ligne 3800 indiquée dans le message d'erreur est celle-ci
TailleOK=$((TailleOK + Taille))
Le problème me semble être dans le nom du répertoire : 'JournalT6SavTestSauvegarde'$'\n''T6SavTestSauvegarde'
:~/SauvegardeJan21$ ls
configAspi17.txt LigneParamChemin
JournalSavFilmsSD5 Old
JournalSavHomePhil ParamChemins.csv
JournalT6SavTestSauvegarde TestD
'JournalT6SavTestSauvegarde'$'\n''T6SavTestSauvegarde' TestZero
Le message d'erreur :
patienter la recherche peut prendre du temps....
1628972342
$TailleTotale :3072
Progression : 2196 / 3072./Aspi.sh: ligne 3800: 4
T6SavTestSauvegarde/20210226T6_Racine
T6_RacineLisezMoi_JournalDeveloppeur.txt : erreur de syntaxe dans l'expression (le symbole erroné est « T6SavTestSauvegarde/20210226T6_Racine
T6_RacineLisezMoi_JournalDeveloppeur.txt »)
Merci pour votre attention
Dernière modification par philoeil (Le 15/08/2021, à 15:46)
Hors ligne
#2 Le 14/08/2021, à 22:13
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Bonjour,
Je me disais qu'il manquait une info voir ci-dessous (pour comprendre correctement le message d'erreur :
phil@phil-G750JH:~/SauvegardeJan21/JournalT6SavTestSauvegardeT6SavTestSauvegarde$ ls
'20210226.2134.T6_Racine'$'\n''T6_RacineLisezMoi_JournalERREURS.txt' '20210226T6_Racine'$'\n''T6_RacineLisezMoi_JournalDeveloppeur.txt' 'ProjetT6_Racine'$'\n''T6_Racine'
Hors ligne
#3 Le 15/08/2021, à 00:25
- Watael
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
pourquoi l'expression T6SavTestSauvegarde est-elle répétée, dans le nom du répertoire, après un "alinéa" ?
si tu passes une liste de répertoire à une commande qui considère l'alinéa comme un séparateur de nom, ça va effectivement être problématique.
c'est pourquoi quand on passe une liste de fichiers à une commande, il faut utiliser le caractère NULL comme séparateur.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#4 Le 15/08/2021, à 06:10
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Bonjour,
Merci Watael
pourquoi l'expression T6SavTestSauvegarde est-elle répétée, dans le nom du répertoire, après un "alinéa" ?
Ce n'est pas volontaire, mais cette erreur m'a fait découvrir une faiblesse de mon script. puisque l'erreur est critique, elle arrête le script
Pour prévenir ce type de problème, je cherche comment traiter ce cas.
c'est pourquoi quand on passe une liste de fichiers à une commande, il faut utiliser le caractère NULL comme séparateur.
Je me sent un peu null :
c'est quoi le caractère NULL ?
(une recherche rapide m'a trouvé ceci :
remplacement carctere nul
Identifier et supprimer les caractères nuls dans UNIXj'ai un fichier texte contenant des caractères nuls non désirés (ASCII NUL, " 151900920" ). Quand j'essaie de le voir dans vi je vois les symboles ^@ , entrelacés dans un texte normal. Comment puis-je:
identifier quelles lignes dans le fichier contiennent des caractères nuls? J'ai essayé de grêler pour " 151900920 " et x0 , mais cela n'a pas fonctionné.
supprimer les caractères nuls? Exécuter strings sur le dossier a tout nettoyé, mais je me demande si c'est la meilleure façon?
et je trouve une solution de substitution mais cela ne me semble pas convenir :
utilisez la commande sed suivante pour supprimer les caractères nuls dans un fichier.
sed -i 's/\x0//g' null.txt
cette solution édite le fichier en place, important si le fichier est encore utilisé. passing-l'ext ' crée une sauvegarde du fichier original avec le suffixe 'ext' ajouté.
)
Dans mon traitement successif de fichiers ici
for Fichier in "${Fichiers[@]}"
do
....
done
comment dois-je faire pour repérer cette présence de caractères spéciaux dans le nom du répertoire, ou de fichier et éviter ce traitement ?
Hors ligne
#5 Le 15/08/2021, à 12:05
- Watael
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
tout affichage, en vue de passer la liste des fichiers à une commande externe, doit utiliser le caractère NULL comme séparateur.
quelques exemples :
$ find -maxdepth 1 -type f -print0 | sort -z | xargs -0 -I {} echo {}
printf '%s\0' | sort -z | xargs -0 -I {} echo {}
for f in .*; do printf '%s\0' "$f"; done | sort -z | xargs -0 -I {} echo {}
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#6 Le 15/08/2021, à 12:20
- kamaris
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Le problème ici vient de
Taille=$(du "${h}/${f}" | sed 's/[[:space:]].*//')
où sed voit deux lignes.
Tu peux utiliser l'option -z :
Taille=$(du "${h}/${f}" | sed -z 's/[[:space:]].*//')
Dernière modification par kamaris (Le 15/08/2021, à 12:21)
Hors ligne
#7 Le 15/08/2021, à 12:37
- Watael
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
oui, ou
taille=$(du -0 "$nomFichier" | sed 's/\s.*//')
ou mieux :
t=$(du "$nomFichier")
t=${t%%$'\t'*}
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#8 Le 15/08/2021, à 13:31
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Bonjour,
Merci Kamaris et Watael
J'essaie de comprendre vos infos
J'ai essayé la solution
Taille=$(du "${h}/${f}" | sed -z 's/[[:space:]].*//')
Message d'erreur identique :
patienter la recherche peut prendre du temps....
1629030005
$TailleTotale :3080
Progression : 2196 / 3080./Aspi.sh: ligne 3802: 4
T6SavTestSauvegarde/20210226T6_Racine
T6_RacineLisezMoi_JournalDeveloppeur.txt : erreur de syntaxe dans l'expression (le symbole erroné est « T6SavTestSauvegarde/20210226T6_Racine
T6_RacineLisezMoi_JournalDeveloppeur.txt »)
Watel je ne comprends pas bien comment mettre en oeuvre ton conseil
J'ai essayé
Taille=$(du "${h}/${f}" | sed 's/\s.*//')
Resultat erreur : "
patienter la recherche peut prendre du temps....
1629030479
$TailleTotale :3080
Progression : 2196 / 3080./Aspi.sh: ligne 3802: 4
T6SavTestSauvegarde/20210226T6_Racine
T6_RacineLisezMoi_JournalDeveloppeur.txt : erreur de syntaxe dans l'expression (le symbole erroné est « T6SavTestSauvegarde/20210226T6_Racine
T6_RacineLisezMoi_JournalDeveloppeur.txt »)
Hors ligne
#9 Le 15/08/2021, à 13:36
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
ReBonjour,
tout affichage, en vue de passer la liste des fichiers à une commande externe, doit utiliser le caractère NULL comme séparateur.
LA récupération de la variable tableau Fichier est fait comme ceci
mapfile -d '' -t Fichiers < <(find "$REPCRD" -not -path '*/\.*' -type f -size +"$TailleMo"M -printf "%h@%f@%s*%c* dernier accès le %AA %Ad %AB %AY à %AH:%AM:%AS*\0")
Que dois-je modifier ?
Dernière modification par philoeil (Le 15/08/2021, à 13:43)
Hors ligne
#10 Le 15/08/2021, à 14:39
- kamaris
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Taille=$(du "${h}/${f}" | sed -E '1{s/^([0-9]+).*/\1/; q}'
?
Hors ligne
#11 Le 15/08/2021, à 15:10
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Bonjour,
Merci Kamaris
Désolé la première correction était bien fonctionnelle je me suis trompé de ligne (pour tot dire j'ai 2 endroits dans le script qui reprenne cette commande j'ai modifié l'une pour l'autre cela ne pouvait pas fonctionner)
LA correction
Taille=$(du "${h}/${f}" | sed -z 's/[[:space:]].*//')
Donne le réultat correct
patienter la recherche peut prendre du temps....
1629036397
$TailleTotale :3080
Progression : 3024 / 3080
1629036398
Temps écoulé =1
Merci et désolé
Hors ligne
#12 Le 15/08/2021, à 15:14
- kamaris
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Mais, au fait, pourquoi recalculer une taille (d'ailleurs approximative) avec du, alors que tu as l'information dans
mapfile -d '' -t Fichiers < <(find "$REPCRD" -not -path '*/\.*' -type f -size +"$TailleMo"M -printf "%h@%f@%s*%c* dernier accès le %AA %Ad %AB %AY à %AH:%AM:%AS*\0")
(à savoir le champ %s).
Il devrait suffire de faire
Taille=${Fichier##*@}
Taille=${Taille%%[^0-9]*}
Que tu peux diviser par 1024 si tu veux retrouver (à peu près) l'approximation de du :
Taille=${Fichier##*@}
Taille=$(( ${Taille%%[^0-9]*} / 1024 ))
Dernière modification par kamaris (Le 15/08/2021, à 15:17)
Hors ligne
#13 Le 15/08/2021, à 15:24
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Merci Watael
(Désolé j'ai retesté la correction sur la bonne ligne)
J'ai testé
Taille=$(du -0 "$nomFichier" | sed 's/\s.*//')
J'obtiens l'erreur
patienter la recherche peut prendre du temps....
1629037265
$TailleTotale :3080
du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
Progression : 0 / 3080du: nom de fichier de longueur nulle incorrect
...
Progression : 0 / 3080
1629037266
Temps écoulé =1
Hors ligne
#14 Le 15/08/2021, à 15:30
- kamaris
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Il faut remplacer "$nomFichier" par "${h}/${f}", mais de toutes façons il faut aussi le -z pour sed.
Hors ligne
#15 Le 15/08/2021, à 15:44
- philoeil
Re : [ RESOLU ] solution pour prevenir un bug du à un nom de fichier
Merci Kamaris
Mais, au fait, pourquoi recalculer une taille (d'ailleurs approximative) avec du, alors que tu as l'information dans...
Et bien voila une très bonne suggestion,
Je corrige ce sera effectivement plus efficace.
On peut mettre ça sur le compte de mon inexpérience et mon lent apprentissage du code shell,
Je corrige c'est effectivement plus sur et efficace
Hors ligne