Précédent   Forum des professionnels en informatique > Systèmes > Linux > Système
Système Vos questions autour de l'administration système
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/11/2011, 19h57   #1
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Par défaut Copie de fichier d'après un historique annexe

Bonjour à tous

Alors, je cherche à récupérer les fichiers images d'un dossier (qui est mise à jour automatiquement) par leur extension (ça pas de soucis) puis je cherche à les copier dans un dossier ou un script php d'un site s'occupe d'eux (renommage et création d'un fichier xml).
Le souci c'est que vu que le script PHP les renomme, quand je relance ma copie il les remet et le script les renomme et ainsi de suite. J'ai donc tenté d'utiliser la commande --backup d'rsync avec un dossier --backup-dir définie, mais cela ne fonctionne toujours pas, il continue de renvoyer les fichier dans le dossier de backup malgré leurs présence dans le dossier 'incremental'. Pas mal de personne m'ont aidé avec Rsync mais je pense être bloqué et surtout je ne suis pas sur qu'Rsync soit la bonne solution.

Voici mon code initial, mais bon il ne fonctionne pas comme je le veux et je pense qu'il faut partir sur quelque chose de différent: un script qui permet de copier des fichiers (ou pas) en fonction d'un historique annexe.

Code :
1
2
3
4
#!/bin/bash
find '/home/nom/image' -name '*.jpg' | while read FILE ; do rsync --backup --backup-dir=incremental --suffix=.old  "$FILE" /var/www/media ; done
wget --spider 'http://monscript.php' ;
#exit 0


Merci d'avance pour votre aide.

PS; un ptit plus serait de remplacer les points par un espace juste après avoir copié les *.jpeg. Mon script a du mal à différencier les deux. Je pensais refaire une commande find et chercher les fichiers puis leur faire sauter leurs point avec 'sed'?
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 22/11/2011, 13h05   #2
Membre actif
 
Inscription : août 2009
Messages : 152
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France

Informations forums :
Inscription : août 2009
Messages : 152
Points : 181
Points : 181
Par défaut refonte complète du script

Perso je referais l'ensemble dans un shell "basique" :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
DEST_DIR=./destination
HIST_DIR=./images_bck
SOURCE_DIR=./images
for file in $(find ${SOURCE_DIR}/ -name '*.jpg');do
  file_name=$(basename ${file})
  if [ ! -f ${HIST_DIR}/${file_name}.old ];then
    # Copie de sauvegarde (a remplacer par un touch ${HIST_DIR}/${file}.old si on veut juste une trace)
    cp -p ${file} ${HIST_DIR}/${file_name}.old
    # Deplacement vers le repertoire de destination
    mv ${file} ${DEST_DIR}
  fi
done
echo "Appel a wget"
C'est plus long, mais plus simple, et plus flexible et évolutif que de continuer avec rsync.
Pour ton problème de "." et de sed je n'ai pas bien saisi ce que tu veux faire.
50Nio est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/11/2011, 13h34   #3
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Citation:
Envoyé par 50Nio Voir le message
Perso je referais l'ensemble dans un shell "basique" :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
DEST_DIR=./destination
HIST_DIR=./images_bck
SOURCE_DIR=./images
for file in $(find ${SOURCE_DIR}/ -name '*.jpg');do
  file_name=$(basename ${file})
  if [ ! -f ${HIST_DIR}/${file_name}.old ];then
    # Copie de sauvegarde (a remplacer par un touch ${HIST_DIR}/${file}.old si on veut juste une trace)
    cp -p ${file} ${HIST_DIR}/${file_name}.old
    # Deplacement vers le repertoire de destination
    mv ${file} ${DEST_DIR}
  fi
done
echo "Appel a wget"
C'est plus long, mais plus simple, et plus flexible et évolutif que de continuer avec rsync.
Pour ton problème de "." et de sed je n'ai pas bien saisi ce que tu veux faire.
Merci beaucoup je vais tester cela.

Pour le "PS" en faite, mon script php considère que ce qui est après le point est l'extension, et quand il y a deux points dans le nom complet du fichier ça fonctionne pas très bien. Je me demandais si je pouvais pas rajouter une fonction pour remplacer le point par un espace. Par contre, il faudrait qu'elle agisse après la copie dans le dossier de destination?
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2011, 13h34   #4
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 071
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 071
Points : 4 154
Points : 4 154
Bonjour,

un shell, même basique, ne fait pas for element in $(commande).

Imagine que commande sorte des éléments contenant des espaces (ou pire, comme il est dit), alors la boucle for itérera sur chacune des composantes de chaque élément.
Et là, patatra !
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/11/2011, 13h38   #5
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Citation:
Envoyé par N_BaH Voir le message
Bonjour,

un shell, même basique, ne fait pas for element in $(commande).

Imagine que commande sorte des éléments contenant des espaces (ou pire, comme il est dit), alors la boucle for itérera sur chacune des composantes de chaque élément.
Et là, patatra !
Aïe, que dois je faire du coup..? :/
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2011, 14h08   #6
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 071
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 071
Points : 4 154
Points : 4 154
Citation:
Envoyé par Benoitt
Aïe, que dois je faire du coup..? :/
Code :
find "$rep" [] -exec sh -c 'commandes_SH' {} {} \;
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/11/2011, 14h11   #7
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Citation:
Envoyé par N_BaH Voir le message
Code :
find "$rep" [] -exec sh -c 'commandes_SH' {} {} \;
Merci N_Bah mais j'ai du mal à faire le lien avec ce qu'il y a avant. Je suis désolé bien regarder, je ne trouve pas.
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2011, 14h40   #8
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 071
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 071
Points : 4 154
Points : 4 154
ce n'est pas le shell qui itère sur la sortie de find, c'est find qui itère les commandes shell pour chaque fichier.
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/11/2011, 16h57   #9
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Citation:
Envoyé par N_BaH Voir le message
ce n'est pas le shell qui itère sur la sortie de find, c'est find qui itère les commandes shell pour chaque fichier.
Je ne comprends pas où tu veux en venir. Désolé.
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2011, 09h42   #10
Membre actif
 
Inscription : août 2009
Messages : 152
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France

Informations forums :
Inscription : août 2009
Messages : 152
Points : 181
Points : 181
Citation:
Envoyé par N_BaH Voir le message
un shell, même basique, ne fait pas for element in $(commande).
Ben, si, le ksh gère ça en natif directement, Unix/Linux etc... ?!? $(commande) est exécuté, tu récupère une liste de chaines de caractères, et le for boucle dessus.

Sinon, le problème des espaces est vrai. Si tes fichiers contiennent des espaces, le for va séparer sur les espaces, donc un fichier "image meteo.jpg" va déclencher deux fois la boucle, une sur "image" et une sur "meteo.jpg". Pour gérer ce cas là, il faut à nouveau tout revoir, soit avec find, soit avec un while.

Pour le find, l'option "-exec" permet d'exécuter une commande sur chaque résultat que le find a trouvé. Dans cette syntaxe "{}" représente ton résultat, et "\;" la fin de la commande shell à exécuter.
Faut que j'essaye, j'ai jamais utilisé find sur des commandes plus complexe qu'un rm par exemple.
50Nio est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 23/11/2011, 11h42   #11
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 071
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 071
Points : 4 154
Points : 4 154
oui, je me suis mal exprimé :
Citation:
en shell, même basique, on ne fait pas (on ne doit pas faire) for element in $(commande).
à force de me répéter, j'essaye de varier un peu, mais là ça n'a pas fonctionné
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 30
Vieux 23/11/2011, 14h07   #12
Membre actif
 
Inscription : août 2009
Messages : 152
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France

Informations forums :
Inscription : août 2009
Messages : 152
Points : 181
Points : 181
Dans ce cas je suis d'accord, la méthode for i in $(commande) est en effet trop simple pour gérer les espaces dans les résultats !

Je n'arrive pas à faire une version avec find qui lancerait une fonction ou plusieurs commandes.

Une version avec while, qui gère les espaces dans les noms de fichier :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/ksh
DEST_DIR=./destination
HIST_DIR=./images_bck
SOURCE_DIR=./images
 
find ${SOURCE_DIR} -name "*.jpg" >${HIST_DIR}/tmp.file
exec 3<${HIST_DIR}/tmp.file
 
while read file <&3;do
  file_name=$(basename "${file}")
  if [ ! -f "${HIST_DIR}/${file_name}.old" ];then
    cp -p "${file}" "${HIST_DIR}/${file_name}.old"
    mv "${file}" "${DEST_DIR}"
  fi
done
exec 3<&-
[ -f ${HIST_DIR}/tmp.file ] && rm -f ${HIST_DIR}/tmp.file
while read valeur <fichier utilise la fin de ligne comme séparateur, pas "tous les blancs", donc va gérer les noms de fichier avec des espaces (et aussi avec des tabulations, mais là franchement ... ptêt le nom du fichier serait abusé).
Autour des commandes mv ou cp, il faut aussi du coup encapsuler tes arguments dans des guillemets pour que le shell interprète "image avec un blanc.jpg" comme un seul argument et non comme 4 arguments distincts.
exec permet d'ouvrir et de fermer proprement des filedescripteurs.
50Nio est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2011, 18h28   #13
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Merci bien. J'y vois petit à petit de plus en plus clair.

J'essaye tout cela.
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/11/2011, 14h53   #14
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Malheureusement je rencontre un message d'erreur à propos du tmp.file

Même si je créé un fichier ou un dossier nommé tmp.file cela ne fonctionne pas...

Code :
1
2
3
benoit@debian:~$ '/home/benoit/Desktop/script4.ksh' 
/home/benoit/Desktop/script4.ksh[6]: ./media/NewVolume/History/tmp.file: cannot create [No such file or directory]
/home/benoit/Desktop/script4.ksh[7]: ./media/NewVolume/History/tmp.file: cannot open [No such file or directory]
Les lignes 6 et 7 étant
Code :
1
2
find ${SOURCE_DIR} -name "*.jpeg" >${HIST_DIR}/tmp.file
exec 3<${HIST_DIR}/tmp.file
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/11/2011, 20h03   #15
Membre actif
 
Inscription : août 2009
Messages : 152
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France

Informations forums :
Inscription : août 2009
Messages : 152
Points : 181
Points : 181
Vérifie que HIST_DIR pointe sur /media/NewVolume/History/ et non pas ./media/NewVolume/History/ ou media/NewVolume/History/

Ton répertoire doit être mal paramétré.
50Nio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2011, 14h23   #16
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Merci beaucoup le script fonctionne pour le moment, malgré le fait que les fichiers du dossier média disparaissent.

J'ai donc fait une modif ligne 13.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/ksh
DEST_DIR=/destination
HIST_DIR=/images_bck
SOURCE_DIR=/images
 
find ${SOURCE_DIR} -name "*.jpg" >${HIST_DIR}/tmp.file
exec 3<${HIST_DIR}/tmp.file
 
while read file <&3;do
  file_name=$(basename "${file}")
  if [ ! -f "${HIST_DIR}/${file_name}.old" ];then
    cp -p "${file}" "${HIST_DIR}/${file_name}.old"
    cp "${file}" "${DEST_DIR}"
  fi
done
exec 3<&-
[ -f ${HIST_DIR}/tmp.file ] && rm -f ${HIST_DIR}/tmp.file
J'ai tenté également d'ajouter une ligne à la fin pour remplacer les points par des underscores.

En utilisant ceci

Code :
1
2
benoit@debian:/var/www/media$ find -name '*.jpg' -execdir rename 's/./_/' {} +
Can't rename ./02. mairie.jpg _/02. mairie.jpg: No such file or directory
Il semblerait que j'ai encore un problème de chemin, je ne comprends pas trop.

Merci encore

Je peux difficilement masquer ma joie.
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2011, 22h47   #17
Invité de passage
 
Inscription : juin 2010
Messages : 10
Détails du profil
Informations forums :
Inscription : juin 2010
Messages : 10
Points : 0
Points : 0
Hello

Bon je suis partie d'un script un peu "assisté" pour arriver à mes fins.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
if [ $# -lt 1 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    echo "" >&2
    echo "Usage: $0 [ -h | --help ]" >&2
    echo "       $0 file .." >&2
    echo "" >&2
    echo "This will transform the name of the specified file(s)." >&2
    echo "" >&2
    exit 0
fi
 
for path in "$@" ; do
    dir="`dirname "$path"`"
    file="`basename "$path"`"
 
    # Split file name and extension
    ext=".${file##*.}"
    old="${file%.*}"
    [ "$old" == "$file" ] && ext=""
    new="$old"
 
    # Modify "$new" to suit your needs. Dots to spaces:
    new="${new//./ }"
 
    if [ "$new" != "$old" ]; then
        mv -vi "$dir/$old$ext" "$dir/$new$ext" || exit $?
    fi
done
Trouvé ici https://www.linuxquestions.org/quest...ension-871417/

Puis je utiliser le path de la ligne 12 avec le $DEST_DIR que j'utilise précédement dans mon script et lui spécifier de suite l'extension. J'ai du mal à trouver.

Pour j'appelle l'ouvre mon dossier puis appel mon script suivis de l’extension *.jpeg

Dernière question, puis-je intégrer ce code en brut dans un script en ksh.
Benoitt est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h02.


 
 
 
 
Partenaires

Hébergement Web