|
|
|
|
||||||
| fr.comp.os.unix Système UNIX. |
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Bonjour,
j'ai des utilisateurs qui peuvent poser des fichiers dans un repertoire. Je souhaite ecrire un script qui scrute un repertoire et qui deplace les fichiers ailleurs dans l'arborescence. Je lancerai ce script via cron toutes les 15 minutes. Je pensais faire un #! /bin/bash for file in `find /var/www/depot/ -type f` do mv $file /var/www/a_traiter/ done Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers n'importe comment (espace, ponctuation, caracteres speciaux) et il arrive que le mv se plante. Comment faire? Merci |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
octane@alinto.com :
> for file in `find /var/www/depot/ -type f` > do > mv $file /var/www/a_traiter/ > done > > > Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers > n'importe comment (espace, ponctuation, caracteres speciaux) et il > arrive que le mv se plante. Il suffit d'utiliser le -exec de find: find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';' .. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On 16 avr, 16:31, Luc.Habert.00__a...@normalesup.org (Luc Habert)
wrote: > > for file in `find /var/www/depot/ -type f` > > do > > mv $file /var/www/a_traiter/ > > done > > > Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers > > n'importe comment (espace, ponctuation, caracteres speciaux) et il > > arrive que le mv se plante. > > Il suffit d'utiliser le -exec de find : > > find /var/www/depot -type f -exec mv '{}' /var/www/a_traiter ';' > oui, mais j'ai un peu plus de choses dans la boucle do .. done Entre autre je fais un echo "un fichier $file a ete transfere" et cron me maile le "echo", et je pense a terme faire des cas selon le fichier (exemple: .doc -> /dev/null, .pdf -> a_traiter/ etc etc..) |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
octane@alinto.com :
> oui, mais j'ai un peu plus de choses dans la boucle do .. done Alors au lieu du mv, tu fais lancer à find un shell exécutant ton corps de boucle: find /var/www/depot -type f -exec sh -c 'for file in "$@"; do corps de la boucle; done' ploum '{}' '+' (tiens, j'avais mis un «;», mais mieux vaut un «+», ça en passe plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)). |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On 16 avr, 17:05, Luc.Habert.00__a...@normalesup.org (Luc Habert)
wrote: > oct...@alinto.com : > > > oui, mais j'ai un peu plus de choses dans la boucle do .. done > > Alors au lieu du mv, tu fais lancer à find un shell exécutant ton corps de > boucle : > > find /var/www/depot -type f -exec sh -c 'for file in "$@"; > do corps de la boucle; done' ploum '{}' '+' > > (tiens, j'avais mis un « ; », mais mieux vaut un « + », ça en passe > plusieurs d'un coup (mais il faut un find pas trop vieux pour ça)). Et je retombe sur mon probleme initial ![]() que dois-je mettre dans <corps de la boucle> pour que le mv me deplace les fichiers sans buter sur un fichier avec des caracteres speciaux? Plus, comment va se comporter le shell et le $@ avec des noms de fichiers avec des caracteres speciaux? |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
octane@alinto.com :
> que dois-je mettre dans <corps de la boucle> pour que le mv me > deplace les fichiers sans buter sur un fichier avec des caracteres > speciaux? Simplement mettre «"$file"» au lieu de «$file». En fait, ce qui se passait avec ce que tu faisais, c'est que dans ton for file in `find /var/www/depot/ -type f` le shell lit la sortie de find, la découpe sur le whitespace (plus précisément les caractères contenus dans la variable IFS qui, par défaut, contient le whitespace), et ensuite fait du globbing (interprétation des * et cie) sur chaque morceau. Avec ce que je t'indique, ce découpage est éliminé: l'écriture «"$@"» est spéciale, elle spécifie que ça donne la liste des arguments passés au script, sans découpage ni globbing. Il reste juste à ce que le «$file» ne se fasse pas découper dans le corps de la boucle, et pour ça, il faut et il suffit de le mettre entre «"» à chaque fois où tu t'en sers. On ne le répètera jamais assez: il faut toujours mettre entre «"» les expansions de variables, sauf si on veut vraiment du découpage et du globbing, ce qui n'arrive pas si souvent que ça. (Et si on ne veut que l'un des deux? Pour désactiver le découpage, il faut vider IFS, et pour désactiver le globbing, il faut faire un «set -f».) |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Luc Habert - <f003cm$cj0$4@nef.ens.fr> :
> j'avais mis un «;», mais mieux vaut un «+ J'ai regardé dans le man find ce que ça signifiait. Pas trouvé. Dans le man du shell (bash)? Trop "long"... Un coup de main? |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
2007-04-18, 09:06(+02), Mihamina (R12y) Rakotomandimby:
> Luc Habert - <f003cm$cj0$4@nef.ens.fr> : > >> j'avais mis un «;», mais mieux vaut un «+ > > J'ai regardé dans le man find ce que ça signifiait. Pas trouvé. Dans le man > du shell (bash)? Trop "long"... Un coup de main? http://www.opengroup.org/onlinepubs/...ties/find.html Ne marche que quand + est l'argument suivant le {} et s'il n'y a qu'un seul {}. Et ca remplace {} par autant de fichiers que possibles. C'est la version standard du -print0 | xargs -r0 de GNU en mieux car il n'affecte pas le stdin des commandes (cela dit, il pourra etre moins efficace car s'il y a plusieurs commandes lancees, find ne continuera pas sa descente pendant que les commandes sont executees). Bien que -exec ... {} + ait ete dans le standard depuis 15 ans et que ca existe depuis 20, je crois que GNU find ne l'a inclu que tres recemment, ca explique peut-etre pourquoi ca n'est pas dans ta page de man. -- Stéphane |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Stephane Chazelas wrote in message
<slrnf2bh9o.5t4.stephane.chazelas@spam.is.invalid> : > Bien que -exec ... {} + ait ete dans le standard depuis 15 ans > et que ca existe depuis 20, je crois que GNU find ne l'a inclu > que tres recemment, ca explique peut-etre pourquoi ca n'est pas > dans ta page de man. Plus précisément, le ChangeLog indique que ça a commencé à fonctionner le 2005-01-15, et que c'est sorti dans la version 4.2.12. |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
octane@alinto.com a écrit :
> Bonjour, > > j'ai des utilisateurs qui peuvent poser des fichiers dans un > repertoire. > Je souhaite ecrire un script qui scrute un repertoire et qui deplace > les fichiers ailleurs dans l'arborescence. > Je lancerai ce script via cron toutes les 15 minutes. > > Je pensais faire un > #! /bin/bash > > for file in `find /var/www/depot/ -type f` > do > mv $file /var/www/a_traiter/ > done > > > Mais ca ne passe pas. Mes utilisateurs nomment leurs fichiers > n'importe comment (espace, ponctuation, caracteres speciaux) et il > arrive que le mv se plante. si find supporte -print0 et xargs -0 (zero), le plus simple est : find /var/depot/www -type f -print0 | xargs -0 -i mv {} /var/www/a_traiter sinon, ca complique un peu, mais sans plus : find /var/depot/www | while read line; do mv "${line}" /var/www/a_traiter done le pb etant le nombre d'execution de la commande mv, 1 par fichier, optimisons donc un peu (a la xargs) : find /var/depot/www -type f | # remplacement de tous les " par \" sed -e 's/"/\\&/g' | ( # longueur maximale de la ligne de commande limit=10000 # valeur initiale args=mv while read line; do # si la limite est atteinte if (( ${#args} + ${#line} + 1 > ${limit} )); then # execution de la ligne de commande prepare eval ${args} /var/www/a_traiter # puis reinitialisation args=mv # pas de continue pour ne pas perdre l'argument courant fi # ajout de l'argument courant a la ligne de commande a executer args="${args} \"${line}\"" done # traitement de ce qui reste eval ${args} /var/www/a_traiter ) non verifie, mais je ne dois pas etre loin de la verite ![]() de toutes les facons, s'il y a un bug, c'est un bon exercice... Regards, Cordialement, Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid supprimer "%nospam% et ".invalid" pour me repondre. remove "%nospam" and ".invalid" to answer me. |
|
![]() |
| Outils de la discussion | |
|
|