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 :
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.
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
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 :
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 ?
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
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
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 ?
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
Effectivement j'ai regardé xargs et c'est exactement ce que je cherchais ! Merci beaucoup pour tes réponses et ta patience
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.
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique
Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique