Partage
  • Partager sur Facebook
  • Partager sur Twitter

Flux de redirection

Utilisation des flux de redirection avec certaines commandes ou script

Sujet résolu
    30 mai 2020 à 19:05:14

    Bonjour,

    Certaines subtilités des flux de redirection (| et <) en particulier m'échappent. J'ai bien compris que "commande1 | commande2" permet de rediriger la sortie de "commande1" en entrée de "commande2", mais alors, pourquoi ça ne marche pas si "commande2" est "echo" par exemple. Autrement dit, pourquoi un simple

    echo "a" | echo

    ne renvoie pas "a" ?
    Je suis d'accord que pour echo ce n'est pas important, mais j'ai le même problème avec mediainfo par exemple. Même chose si je fais "commande1 > fichier.txt" puis "commande2 < fichier.txt". Pour contourner le problème (quel qu'il soit), je fais un script qui contient :

    cat $1 | while read ligne
    do
    echo $ligne
    done

    alors dans ce cas ça marche avec ".script.sh < fichier.txt" mais pas avec "commande1 | .script.sh". Il me semblait pourtant que c'était le contenu du fichier qui était fourni en entrée avec '<' et pas le fichier lui-même... Et si j'essaye de mettre simplement :

    echo $1

     dans le script, alors aucun des deux ne marche.

    Quelqu'un a une explication ?

    Merci d'avance !



    • Partager sur Facebook
    • Partager sur Twitter
      30 mai 2020 à 20:01:55

      salut,

      1- parce que echo ne lit pas sont entrée standard

      2- le cat lit le premier argument passé au script. Enlève-le, ainsi que le pipe (bien sûr), et la boucle lira la redirection du fichier.

      ce que tu as fait s'appelle un UUOC (Useless Use Of Cat)
      pour lire un fichier dont le nom est passé en argument, on redirige le contenu du fichier "dans la boucle" :

      if test -f "$1"
      then
          while read -r line
          do
             echo "$line"
          done <"$1"
      fi

      et tu l'exécutes (après l'avoir rendu exécutable) comme ça :

      $ ./monScript monFichier

      il faut distinguer ce qui est de l'ordre des arguments passés au script, et ce qu'est son entrée standard.

      • Partager sur Facebook
      • Partager sur Twitter

      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

        31 mai 2020 à 13:24:28

        Salut,

        Merci pour ta réponse. Ce que je ne comprends pas alors ça doit être la différence entre arguments et entrée standard. J'avais bien remarqué que .monScript monFichier marche comme je veux, mais alors :
        1) pourquoi dans mon cas ça marche aussi avec monScript < monFichier ?
        2) pourquoi ça ne marche pas avec | ?
        3) comment je peux passer la sortie d'une commande en argument du script sans écrire dans un fichier ?

        Là je l'ai fait avec echo, mais globalement mon problème c'est que je voudrais utiliser la commande mediainfo sur une liste de fichier donnée par un find, avec un truc de ce genre :

        find . -type f -name [...] -printf "%p\n" | mediainfo

        Pour l'instant la meilleure solution que j'ai trouvée c'est de mettre la commande mediainfo dans un script comme ci-dessus et de faire :

        find . -type f -name [...] -printf "%p\n" > fichier.txt
        script fichier.txt

        mais ce n'est pas très élégant et surtout j'aimerais comprendre pourquoi les autres méthodes ne marchent pas...


        • Partager sur Facebook
        • Partager sur Twitter
          31 mai 2020 à 14:42:02

          dans ton cas, il faut utiliser l'option -exec:
          find ... -exec mediainfo {} \;
          find va exécuter mediainfo pour chaque fichier qu'il trouvera.
          • Partager sur Facebook
          • Partager sur Twitter

          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

            31 mai 2020 à 17:03:33

            Ah oui, c'est beaucoup plus simple et élégant, merci ! Par contre c'est spécifique à find, non ? Dans mon cas c'est bien ce qui m'intéresse mais j'aimerais bien comprendre de manière plus générale, si par exemple je voulais rediriger la sortie de ls vers mediainfo je ne pourrais pas faire comme ça, si ? Ou si je veux utiliser le résultat d'une commande quelconque comme argument d'un script ou d'une fonction ?
            • Partager sur Facebook
            • Partager sur Twitter
              31 mai 2020 à 18:20:54

              d'une manière générale :

              sans autre indications, ce qui suit un script, c'est les arguments.
              Ils sont accessibles via le paramètre spécial ($@) et/ou les paramètres positionnels ($1, $2... ${10}, ${11}...).

              quand il y a un pipe avant, ou une redirection après, alors les données sont transmises sur l'entrée standard du script.

              il semble que mediainfo n'utilise que des arguments.

              on n'utilise pas la sortie de ls (ou tellement rarement; autant dire jamais), parce que les noms des fichiers ne sont pas protégés; on passe par le Développement des chemins (cf. le man).

              après ça dépend de la commande : il n'y a pas de comportement standardisé.
              certains ne lisent qu'un seul argument, certains lisent les données sur leur entrée standard.
              d'autres pas.

              -
              Edité par dantonq 31 mai 2020 à 18:22:19

              • Partager sur Facebook
              • Partager sur Twitter

              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                31 mai 2020 à 18:57:36

                D'accord merci c'est très clair ! Du coup si je veux utiliser la sortie d'une commande1 comme argument d'une commande2, la solution générale c'est bien de faire : "commande2 $(commande1)" ? Il y a un équivalent pour un nombre d'arguments variable ?


                • Partager sur Facebook
                • Partager sur Twitter
                  31 mai 2020 à 20:10:11

                  Il y a un équivalent pour un nombre d'arguments variable ?

                  je ne comprends pas la question.

                  la solution générale c'est bien de faire : "commande2 $(commande1)" ?

                  je te l'ai dit, ça dépend de la façon dont la commande prend ses arguments ou lit son entrée standard.

                  cependant, cette manière de faire peut être problématique dans le cas où les arguments contiennent des espaces, tabulations, ou alinéas.

                  renseigne-toi sur xargs

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                    31 mai 2020 à 20:51:55

                    Oui, j'ai compris que ça dépend, je parle du cas où commande2 ne lit pas son entrée standard mais des paramètres, comme mediainfo.
                    Par "nombre d'arguments variables" je parle d'une commande qui peut avoir n'importe quel nombre d'arguments à la suite et qui les traite tous un par un (comme mediainfo). Par exemple (même si je sais qu'il n'est pas bon car il y a plus simple), si je fais

                    mediainfo $(find . -name *.avi -printf "%p")

                    ça a l'air de marcher s'il n'y a qu'un seul résultat (un seul fichier .avi, à condition qu'il n'y ait pas d'espaces comme tu le fais remarquer), mais par contre je ne vois pas de moyen de produire le résultat attendu s'il y a plusieurs fichiers trouvés

                    • Partager sur Facebook
                    • Partager sur Twitter
                      31 mai 2020 à 20:59:55

                      je te l'ai dit, c'est risqué.

                      pour find, il y a -exec.
                      pour les autres, le mieux c'est d'utiliser xargs.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                        31 mai 2020 à 21:17:52

                        Effectivement j'ai regardé xargs et c'est exactement ce que je cherchais ! Merci beaucoup pour tes réponses et ta patience :)
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Flux de redirection

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown