IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

find et -exec


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Consultant communication & réseaux
    Inscrit en
    Février 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant communication & réseaux

    Informations forums :
    Inscription : Février 2017
    Messages : 2
    Par défaut find et -exec
    Bonjour

    Je souhaite faire un mv de toutes les photos que j'ai dans un $HOME vers un directory type bkp_Photos.

    J'ai essayé la commande suivante sans grande réussite. Je n'arrive pas à comprendre pourquoi elle ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cd ~
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos \;
    Merci pour votre aide.

    dbox911.

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 713
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 713
    Par défaut
    Bonjour,

    « ça marche pas » : les images ne sont pas déplacées ?
    est-ce qu'il y a un message d'erreur ?

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par dbox911 Voir le message
    J'ai essayé la commande suivante sans grande réussite. Je n'arrive pas à comprendre pourquoi elle ne fonctionne pas.
    Ma boule de cristal étant actuellement chez le réparateur, difficile de deviner ce qui ne va pas...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cd ~
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos \;
    A priori, la commande n'a pas l'air trop mal! Avec juste 2-3 bémols...

    Est-ce que le répertoire ./bkp_Photos existait bien avant le premier lancement?
    Que répond ls -ld ./bkp_Photos, voire file ./bkp_Photos?
    Car, si le répertoire n'existait pas avant le premier lancement de la commande, alors, à cause du ';', le premier "mv" va déplacer et renommer la première photo en ./bkp_PhotosDe plus, s'il y a déjà des photos dans ./bkp_Photos, il est probable que "find" va les trouver et que "mv" ne va pas être d'accord de devoir les déplacer où elles sont déjà... (quelle idée d'avoir une commande pour 2 actions différentes (déplacer et renommer)!)

    Et j'aurais soit utilisé '+' soit mis un '/' au répertoire (soit les deux):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+' # OOPS!


    EDIT:
    Attention, ça ne marche pas avec '+' (voir messages suivants)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ ';'

  4. #4
    Nouveau candidat au Club
    Homme Profil pro
    Consultant communication & réseaux
    Inscrit en
    Février 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant communication & réseaux

    Informations forums :
    Inscription : Février 2017
    Messages : 2
    Par défaut
    Bonsoir

    Je vous remercie pour vos retours. J'ai refait le test en m'assurant que les directories étaient bien présents et en me placant dans un directory different. Tout fonctionne.
    Je garde l'idée du '+' et du '/'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cd /home/user1
    find ./photo -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'

    Merci pour votre aide et support
    Dbox911.

  5. #5
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'
    Hmm, tu es sûr ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'
    find: paramètre manquant pour «*-exec*»
    $ find --version | head -1                           
    find (GNU findutils) 4.7.0-git

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    Hmm, tu es sûr ?
    Ben... non...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'
    find: paramètre manquant pour «*-exec*»
    $ find --version | head -1                           
    find (GNU findutils) 4.7.0-git
    J'ai toujours beaucoup de mal à faire marcher _mon_ find avec '+' alors qu'avec ';' y a pas de problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+'
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ +
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \;
    mv foo.jpeg ./bkp_Photos/
    mv bar.jpeg ./bkp_Photos/
     
    $ find --version
    find: illegal option -- -
    usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
           find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
     
    $ uname -a
    Darwin MBPR15-jack 15.6.0 Darwin Kernel Version 15.6.0: Mon Jan  9 23:07:29 PST 2017; root:xnu-3248.60.11.2.1~1/RELEASE_X86_64 x86_64
    Hum... je crois que j'ai trouvé (rtfm...):
    $ man find
    -exec utility [argument ...] {} +
    Same as -exec, except that ``{}'' is replaced with as many pathnames as possible for each invocation of utility. This behaviour is similar to that of xargs(1).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} +
    mv foo.jpeg bar.jpeg
    Manifestement, il faut que "{}" soit juste avant "+", ce qui est le cas, par exemple, pour un "grep" où l'on veut voir le nom des fichiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ find . -name "*.txt" -exec grep "chaine" {} +
    Mais apparemment il ne peut pas expanser "{}" avec la liste des fichiers s'il y a autre chose derrière.

    Je ne vois donc pas comment faire un mv *.jpeg ./bkp_Photos/ en un seul "mv" avec "find"...

    Mais la solution avec / et ';' tient toujours:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ ';'

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par dbox911 Voir le message
    J'ai refait le test en m'assurant que les directories étaient bien présents et en me placant dans un directory different. Tout fonctionne.
    Bonne nouvelle!

    et pense au bouton

    Je garde l'idée du '+' et du '/'
    Euh... garde l'idée du '/' mais abandonne celle du '+'...

  8. #8
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 713
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 713
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -exec mv --target-directory=DIRECTORY {} +

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2013
    Messages : 153
    Par défaut
    Pour varier, zsh :
    Avec le globbing récursif, il n'y a pas besoin de find. En plus, il n'y a pas de problèmes si des noms des fichiers contiennent des espaces.

  10. #10
    Membre confirmé Avatar de Bragu Demon
    Homme Profil pro
    Intégrateur d'Explopitation
    Inscrit en
    Juin 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Intégrateur d'Explopitation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2013
    Messages : 125
    Par défaut
    Autre variante :

    depuis le dossier contenant les photos :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls *.jpg | awk '{print "mv "$1" /chemin/vers/les/dossier/bkp_Photos/"}' | sh
    ls -> ben un bête listing avec juste le nom des fichiers
    awk -> permet "d'écrire", le $1 étant le fichier précédemment listé
    sh -> exécute
    les pipe ("|") -> permettent d'enchaîner les commandes

    Dans un premier temps il vaut mieux exécuter sans le sh
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls *.jpg | awk '{print "mv "$1" /chemin/vers/les/dossier/bkp_Photos/"}'
    pour voir ce que ça donne.

    Exemple :
    si le dossier /home/toto/photo/ contient :
    chien.jpg
    chat.jpg
    ours.jpeg
    pingouin.gif

    alors ls *.jpg | awk '{print "mv "$1" /chemin/vers/les/dossier/bkp_Photos/"}' doit retourner :
    mv chien.jpg /chemin/vers/les/dossier/bkp_Photos/
    mv chat.jpg /chemin/vers/les/dossier/bkp_Photos/

    et en rajoutant le "| sh", on ne verra rien, et en allant dans le dossier /chemin/vers/les/dossier/bkp_Photos/ pour y voir les fichier déplacés.

  11. #11
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 713
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 713
    Par défaut
    en espérant très fort qu'il n'y a pas d'espaces dans les noms des fichiers !

  12. #12
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Bragu Demon Voir le message
    Autre variante :

    depuis le dossier contenant les photos :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls *.jpg | awk '{print "mv "$1" /chemin/vers/les/dossier/bkp_Photos/"}' | sh
    Euh... il me semble que ta commande ne marche que si tous les fichiers de photos sont dans le même répertoire!

    Auquel cas, personnellement et en ce qui me concerne moi-même en personne, je ferais plutôt (bêtement):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mv *.jpg /chemin/vers/les/dossier/bkp_Photos/

  13. #13
    Membre confirmé Avatar de Bragu Demon
    Homme Profil pro
    Intégrateur d'Explopitation
    Inscrit en
    Juin 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Intégrateur d'Explopitation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2013
    Messages : 125
    Par défaut
    Pour répondre aux 2 messages précédent, je vis dans un monde où tous les fichiers sont sans espaces et rangés de façon "logique" (la mienne).
    Si le besoin est de simplement prendre des fichiers d'un dossier pour les mettre ailleurs, alors le mv est LA réponse (toujours aller vers le plus simple) je suis biens d'accord.

    ls -l | grep '^d' | awk '{ print $9 }' répondra certainement au besoin de récupérer le nom des fichiers. Je n'ai pas de linux sous la main là, mais il serait intéressant de récupérer les fichiers et leur chemin à partir d'un dossier source afin de recréer "automagiquement" l'arborescence source dans le dossier cible. Du point de vue de l'exploitant c'est plutôt intéressant, en cas de besoin de restauration, on connais déjà l'arborescence cible à retrouver, mais on s'éloigne un peu de la question.

    après n'étant pas particulièrement linuxien (je fais du ZOS toute la journée et du linux pour me reposer, le tout à partir d'un poste windows ) il y a certainement des solution beaucoup plus simple

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 871
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    J'ai toujours beaucoup de mal à faire marcher _mon_ find avec '+' alors qu'avec ';' y a pas de problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+'
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ +
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \;
    Bonjour

    Manifestement tu ne piges pas trop pourquoi le "+", pourquoi le ";" et pourquoi le "\"...

    Quand tu lances find -exec, tu es sensé mettre une commande après le -exec. Mais une commande peut avoir plusieurs syntaxes. Ca peut être commande, ou bien commande arg1, pu bien commande arg1 arg2. Bref le find ne connait pas à l'avance le format de ta commande.
    Il te faut donc donner une indication au find sur la commande et notamment l'endroit où elle se termine. Parce que si tu tapes find . -type f -exec ls {} -print on ne peut pas, à priori, savoir si le -print est une option du find ou un argument de la commande ls.
    Cette indication est donc donnée par le caractère ";" ou bien par le caractère "+". Le ";" demande au exec d'exécuter la commande pour chaque fichier trouvé pris un par un ; et le "+" demande au exec d'exécuter la commande pour un maximum de fichiers d'un coup.
    Cependant le ";" est aussi un méta-caractère du shell. Si on veut que le find le reçoive tel quel, il faut alors le protéger lors de l'appel donc un backslash (ou alors des quotes). En revanche, le "+" n'est pas un méta-caractère donc pas besoin de quoi que ce soit.

    Il reste un détail avec le "+" car ça demande au -exec d'intégrer tous les fichiers d'un coup à la commande. Mais dans ce type d'écriture -exec mv {} ./bkp_Photos, comment le -exec va insérer les fichiers au mv ? Si par exemple il y en a 3 "fic1" "fic2" et "fic3", va-t-il l'insérer de cette façon: mv fic1 fic2 fic3 ./bkp_Photos (ce qui est correct) ou bien plutôt mv fic1 ./bkp_Photos fic2 fic3 (ce qui ne correspond à plus rien de logique) ?
    C'est pourquoi le "+" ne peut se mettre que pour des commandes qui n'ont pas à recevoir d'autres arguments que le ou les fichiers à traiter (ex: ls, rm, md5sum, echo, etc...).

    Exemples possibles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ \;
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ ';'
    $ find . -name "*.jpeg" -exec ls -l {} \;
    $ find . -name "*.jpeg" -exec ls -l {} +
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2013
    Messages : 153
    Par défaut
    Citation Envoyé par Bragu Demon Voir le message
    il serait intéressant de récupérer les fichiers et leur chemin à partir d'un dossier source afin de recréer "automagiquement" l'arborescence source dans le dossier cible. Du point de vue de l'exploitant c'est plutôt intéressant, en cas de besoin de restauration, on connais déjà l'arborescence cible à retrouver, mais on s'éloigne un peu de la question.
    Ça serait rsync, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rsync -avm --include='*/' --include='*.jpeg' --exclude='*' --remove-source-files dir-with-files/ backup-dir
    Ici on ne copier que les fichiers jpeg. On assume que backup-dir n'est pas un sous-répertoire de dir-with-files, ce qui est plus naturel et plus simple.

  16. #16
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Manifestement tu ne piges pas trop pourquoi le "+", pourquoi le ";" et pourquoi le "\"...
    Si si, j'ai bien compris!

    C'était juste que, avant de lire le "man", j'imaginais que "{}" s'expansait en la liste des fichiers concernés et que j'étais "enduit" d'erreur par le message de "find":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+'
    find: -exec: no terminating ";" or "+"
    Quand je lisais ce message d'erreur, j'étais pour le moins perplexe et confus!
    Pourquoi me dit-il que le "-exec" du "find" n'est pas terminé par ";" ou "+" alors qu'il est clair que si???
    La confusion vient aussi en partie du fait que c'est exactement le même message que lorsqu'on "oublie" de quoter le ";":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ ;
    find: -exec: no terminating ";" or "+"
    Mais merci quand même pour tes explications (qui ont au moins le mérite d'être claires)!

    [HS]
    Pour la petite histoire, je n'ai réellement compris que récemment (probablement sur ce forum, il y a moins d'une décennie) le fonctionnement de l'option "-exec" de "find" avec le terminateur "\;" que j'ai bien utilisé, puis encore plus récemment (probablement sur ce forum, il y a moins d'un lustre) celui du terminateur "+". Comme je le disais plus haut, c'est bien pratique pour faire apparaître le nom des fichiers lors de l'utilisation d'un "-exec grep", surtout si l'on ne connait pas l'option "-H" de "grep"...
    [/HS]

  17. #17
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Pourquoi me dit-il que le "-exec" du "find" n'est pas terminé par ";" ou "+" alors qu'il est clair que si???
    La confusion vient aussi en partie du fait que c'est exactement le même message que lorsqu'on "oublie" de quoter le ";":
    Il te dit que le -exec n'est pas terminé par ";" ou "+" tout simplement parce que le "-exec" n'est effectivement terminé ni par un "+", ni par un ";" puisqu'il n'est pas terminé du tout.

    Comme la page de manuel de find doit l'indiquer, un "-exec" doit être terminé par ";" ou "+" et le "+" doit être obligatoirement précédé de "{}" pour être compris comme délimiteur de fin.

    Comme ce n'est pas le cas avec ta commande, ce "+" n'a pas de signification pour find et il est traité comme un argument comme un autre. Si ce n'était pas le cas, il serait impossible d'utiliser une commande ayant comme argument un "+" dans la clause "-exec".

    La documentation POSIX est très claire la dessus:

    The end of the primary expression shall be punctuated by a <semicolon> or by a <plus-sign>. Only a <plus-sign> that immediately follows an argument containing only the two characters "{}" shall punctuate the end of the primary expression. Other uses of the <plus-sign> shall not be treated as special.

  18. #18
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Jiliagre, je ne souhaite pas polémiquer car je suis complètement d'accord avec toi!
    J'ai bien tout compris et ne me ferai probablement plus avoir!

    J'ai juste besoin d'être entendu lorsque je dis que le message de "find" n'est pas facile à comprendre, notamment pour un débutant.

    En toute bonne foi, lorsqu'un débutant (ou quelqu'un qui ne connait pas bien le "find" et qui n'a pas suffisamment lu le "man" ou la documentation, aussi claire soit-elle) écrit find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+' et qu'il voit le message d'erreur disant que le "-exec" n'est pas terminé par un "+", franchement, je trouve qu'il n'est pas aberrant de se sentir dérouté... même si "find" a sa logique parfaitement logique!

    C'est un peu toujours le même problème: le message d'erreur doit-il indiquer ce qui ne va pas (notamment en termes d'analyse lexicale) ou bien fournir des pistes pour corriger l'erreur?

    Peut-être vous souvenez-vous des compilateurs Pascal des années 80 dont le parser continuait l'analyse et générait des messages complètement incompréhensibles lorsqu'on avait juste oublié un ";" en fin de ligne...

    Pour en terminer sur ce sujet, si "find" avait affiché le message suivant, il est fort probable que le débutant (ou moi-même) aurait tout de suite compris comment corriger son erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: should be terminated with "\;" or "{} +"

  19. #19
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Pour en terminer sur ce sujet, si "find" avait affiché le message suivant, il est fort probable que le débutant (ou moi-même) aurait tout de suite compris comment corriger son erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: should be terminated with "\;" or "{} +"
    Oui, pourquoi pas, encore que le "\" est un problème lié au shell, pas à find, et qu'il y a d'autres possibilités comme le mettre entre simples ou doubles quotes.

    Mais tu peux toujours soumettre un patch à la FSF pour GNU find, puisque c'est open source.

    Pour les aspects techniques, c'est un peu plus compliqué que ça en a l'air, car les fameux ";" ou "{} +" ne terminent pas forcément la commande find, il peux très bien y avoir d'autres directives après le "-exec", ou y avoir plusieurs "-exec", et dans le -exec tout doit être ignoré par le parser. Ce qui parait simple en surface ne l'est pas nécessairement quand il s'agit de construire un parser capable de traiter correctement toutes les commandes valides d'après le standard (+ les extensions GNU ici)

  20. #20
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 871
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    même si "find" a sa logique parfaitement logique!
    J'adore ce genre de phrase

    Citation Envoyé par jack-ft Voir le message
    C'est un peu toujours le même problème: le message d'erreur doit-il indiquer ce qui ne va pas (notamment en termes d'analyse lexicale) ou bien fournir des pistes pour corriger l'erreur?
    Ca peut se discuter. Mais n'oublions pas que ces outils ont vu le jour sous Unix, OS professionnel développé par des professionnels pour des professionnels. Et même si Linux tend à se plébisciter (surtout avec ses déclinaisons Ubuntu qui se veulent résolument grand public), quand on en est à faire de la ligne de commande c'est qu'on a déjà un certain niveau placé au dessus de celui qui se contente de regarder des films et donc qu'on est capable de lire un message et extrapoler les actions correctives...

    Citation Envoyé par jack-ft Voir le message
    Peut-être vous souvenez-vous des compilateurs Pascal des années 80 dont le parser continuait l'analyse et générait des messages complètement incompréhensibles lorsqu'on avait juste oublié un ";" en fin de ligne...
    Ah mais ça arrive encore aujourd'hui notemment avec le cc/gcc. Et c'est normal. Si la ligne X n'a pas de ";" qui la termine, il pense alors que la ligne se continue en ligne "X+1" Et comme généralement la concaténation des deux lignes ne signifie rien de syntaxiquement correct... Et c'est pour ça que s'il est indiqué une erreur en ligne (par exemple) 25 et que la ligne 25 est correcte, il faut alors aller immédiatement voir la ligne 24 (et parfois même on ne va même plus voir la ligne 25...)

    Citation Envoyé par jack-ft Voir le message
    Pour en terminer sur ce sujet, si "find" avait affiché le message suivant, il est fort probable que le débutant (ou moi-même) aurait tout de suite compris comment corriger son erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: should be terminated with "\;" or "{} +"
    Non, il ne pourra jamais afficher with "\;" parce que -exec veut juste un simple point-virgule, rien d'autre. C'est toi qui est obligé de rajouter un outil de neutralisation de métacaractères (backslash ou quotes) pour que ce point-virgule que tu tapes ne soit pas trappé par le shell qui interprète ta ligne de commande et soit transféré au find. Bref dans -exec xxx {} \; le point-virgule c'est pour le find et le backslash c'est pour le shell.
    Si par exemple tu passes par un autre interpréteur pour lequel le point-virgule ne serait pas un métacaractère, tu n'as plus besoin de le protéger. Et si, inversement, tu rajoutes une surcouche au dessus du shell, et que dans cette surcouche le backslash est lui-aussi un métacaractère, tu devras alors le doubler.
    Exemple C
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <stdio.h>
     
    int main()
    {
    	system("find /tmp -type f -exec ls -l {} \\;");   // Double backslash parce que le C en récupère déjà un avant d'appeler "system()" (qui génèrera un shell)
    }

    Donc le find ne prend en charge que ce qui la concerne. Parce que tu ne peux pas lui demander de gérer (en plus de ses problèmes) les caractéristiques de l'environnement spécifique qui l'appelle.
    Et bon, le "débutant" il ne reste jamais débutant très longtemps. Je pense que plus jamais ni toi ni dbox911 (s'il est resté et qu'il a testé les exemples) ne feront désormais d'erreur de -exec et donc inutile pour les programmeurs de la commande de se casser le noeud à prévoir des messages qui ne seront utiles qu'une fois dans la vie. Bref leur philosophie c'est "on est déjà pas mal charrette alors on indique le minimum et Vae Victis"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. [OS X] [SH] Utilisation de find et -exec
    Par medmaysais dans le forum Shell et commandes POSIX
    Réponses: 2
    Dernier message: 13/03/2016, 22h11
  2. Utiliser exec plusieurs fois dans find
    Par Tex-Twil dans le forum Shell et commandes GNU
    Réponses: 0
    Dernier message: 12/03/2008, 15h49
  3. utilisation de l'option -exec de find
    Par panach91 dans le forum Shell et commandes GNU
    Réponses: 10
    Dernier message: 17/01/2008, 12h34
  4. verifier la suppression dans le exec du find
    Par decksroy dans le forum Linux
    Réponses: 4
    Dernier message: 04/12/2007, 12h45
  5. [find] Problème avec -exec
    Par kromartien dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 06/11/2007, 18h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo