Forum Linux.débutant Commande find et déspécialisation

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
4
22
août
2018

Bonjour à tous,

Je tombe sur un cas spécial. Dans mon cours d'OS, le prof utilise la commande suivante : find . -name \*.jpg

Je pensais que le caractère serait déspécialisé et donc que le fichier '*.jpg' serait trouvé mais pas du tout il trouve bien tous les fichiers se terminant par .jpg.

Du coup voici ma question : quelle est la différence entre find . -name *.jpg et la commande find . -name \*.jpg

Merci d'avance !

  • # * est un caractère spécial

    Posté par  . Évalué à 1. Dernière modification le 22 août 2018 à 16:25.

    L'étoile est un joker dans le shell : ca veut dire n'importe quelle caractère/chaîne de caractère (y compris l'absence de caractère)

    quelle est la différence entre find . -name *.jpg et la commande find . -name *.jpg

    Pour trouver le fichier *.jpg, tu dois indiquer au shell de ne pas interpréter l'* à l'aide d'un \ ou bien en mettant le nom de ton fichier entre '

    http://www-inf.it-sudparis.eu/cours/UNIX/Web/6.36.html
    http://www-inf.it-sudparis.eu/cours/UNIX/Web/6.37.html

    • [^] # Re: * est un caractère spécial

      Posté par  (site web personnel) . Évalué à 10.

      Le cas de find est particulièrement tordu. En pratique il y a 3 cas :

      find . -name '*.jpg'  # ou \*.jpg, ou "*.jpg"
      

      => Trouve tous les fichiers se terminant par .jpg, dans le répertoire courant et ses sous-répertoires. C'est en général ce qu'on veut. Le shell va passer *.jpg sans expansion à find, qui fait le boulot.

      find . -name *.jpg
      

      => Si il existe un fichier terminant par .jpg dans le répertoire courant (disons foo.jpg), alors le shell va faire l'expansion, et la commande réelle sera find . -name foo.jpg, qui va trouver tous les fichiers nommés foo.jpg dans le répertoire courant et ses sous-répertoires. C'est probablement une bêtise.

      => Si il n'existe pas de fichier terminant par .jpg dans le répertoire courant, alors le shell va tenter l'expansion, qui va échouer. La plupart des shells (bash compris) vont laisser *.jpg tel quel, et la commande sera donc bien find . -name *.jpg qui fera ce qu'on attend. C'est un coup de chance, mais c'est probablement une bêtise aussi.

      • [^] # Re: * est un caractère spécial

        Posté par  (Mastodon) . Évalué à 4.

        ah, merci !!!

        je me posais depuis belle lurette la question du journal.

        donc en fait techniquement c'est une mauvaise idée, il vaudrait mieux faire '*.jpg' afin d'être certain que le shell (quel qu'il soit) n'expande rien et envoie la formule telle quelle.

        En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

        • [^] # Re: * est un caractère spécial

          Posté par  (site web personnel) . Évalué à 3. Dernière modification le 23 août 2018 à 17:08.

          donc en fait techniquement c'est une mauvaise idée, il vaudrait mieux faire '*.jpg' afin d'être certain que le shell (quel qu'il soit) n'expande rien et envoie la formule telle quelle.

          Oui, clairement.

          En fait, ce qui aurais été bien, c'est que le shell provoque une erreur quand l'expansion de wildcard ne marche pas. C'est ce que fait zsh par exemple :

          bash$ echo *.nosuchext
          *.nosuchext
          zsh$ $ echo *.nosuchext
          zsh: no matches found: *.nosuchext
          

          La solution de bash, qui sauf erreur de ma part date du Bourne Shell original, est à mon avis choisie par flemme des concepteurs de faire des erreurs propres : le shell passe le wildcard en l'état à la commande en espérant que la commande en fasse quelque chose de pertinent. Des fois, ça marche :

          $ ls *.nosuchext
          ls: cannot access '*.nosuchext': No such file or directory
          

          Pour find, le résultat est on ne peut moins déroutant.

          Un intérêt de la solution zsh est aussi que ça permet un super jeu de mots :

          $ have fire ?
          zsh: no matches found: ?
          

          ;-)

          • [^] # Re: * est un caractère spécial

            Posté par  . Évalué à 4.

            Dans bas, c'est le comportement par défaut, mais on peut le changer:

            shopt -s failglob

            Si tu le met dans ton .bashrc (voir au niveau global) ce sera activé par défaut.

            À la place de failglob, il y a aussi nullglob qui est intéressant dans les scripts (par exemple pour faire une boucle sur tous les fichiers, y compris s'il n'y en a pas).

    • [^] # Re: * est un caractère spécial

      Posté par  . Évalué à 4.

      Pour compléter la réponse de Marco : les jokers sont interprétés par le shell. Il remplace l'expression par les fichiers qu'il trouve PUIS exécute la commande.
      Exemples :

      find . -name toto.jpg --> le shell exécute la commande find . -name toto.jpg (aucun changement)
      find . -name t*.jpg --> le shell exécute la commande find . -name toto.jpg titi.jpg tutu.jpg (ce qui est une erreur de syntaxe)
      find . -name 't*.jpg' --> find . -name t*.jpg (les guillemets sont supprimés. C'est le shell qui les supprimer toujours)

      Tu peux le mettre en évidence avec la commande echo :

      echo * --> le shell exécute la commande echo fichier.txt truc.bin chose.xls (au final ça affiche la liste des fichiers)

      Pour que l'étoile soit transmise comme argument il faut l'échapper avec \* ou entre guillemets (simples ou doubles en Bash).

      echo "*" --> le shell exécute la commande echo * (et donc affiche une étoile)

      La commande find a la particularité d'interpréter les jokers (donc *.jpg va afficher tous les fichiers avec extention jpg), mais la plupart des commandes qui reçoivent un joker le considère comme un caractère normal.

      Sous MS-DOS le shell n'a pas « conscience » des jokers, ils sont donc passés directement aux commandes qui doivent les gérer.

  • # Bigleux ?

    Posté par  (site web personnel) . Évalué à 5.

    quelle est la différence entre find . -name *.jpg et la commande find . -name *.jpg

    C'est moi où il n'y a aucune différence entre les 2 commandes indiquées ! ? !

    • [^] # Re: Bigleux ?

      Posté par  . Évalué à 1.

      Ne vois tu pas la différence entre
      find . -name *.jpg et find . -name *.jpg
       ?

    • [^] # Re: Bigleux ?

      Posté par  (Mastodon) . Évalué à 1.

      je suppose que c'est avec et sans les simples cotes.

      En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

      • [^] # Re: Bigleux ?

        Posté par  . Évalué à 1.

        C'est le caractère \ qui est mangé par Markdown lorsqu'il précède un *

    • [^] # Re: Bigleux ?

      Posté par  (site web personnel) . Évalué à 3.

      C'est plus visible/compréhensible si les commandes sont protégées par des backquotes en markdown.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.