222 votes

Script Bash, lit les valeurs de stdin pipe

J'essaie de faire bash pour traiter les données de stdin qui est diffusé, mais pas de chance, ce que je veux dire n'est aucun des travaux suivants:

 echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=


echo "hello world" | read test; echo test=$test
test=


echo "hello world" | test=`cat`; echo test=$test
test=
 

où je veux que la production soit test=hello world . Remarque J'ai essayé de mettre "" des citations autour de "$test" qui ne fonctionnent pas non plus.

178voto

yardena Points 812

Utilisation

IFS= read var << EOF
$(foo)
EOF

Vous pouvez tromper read dans l'acceptation d'un tuyau comme ceci:

echo "hello world" | { read test; echo test=$test; }

ou même écrire une fonction comme ceci:

read_from_pipe() { read "$@" <&0; }

Mais il n'y a pas de point - vos affectations de variables ne peut pas durer! Un pipeline peut générer un shell interne est exécuté, où l'environnement est héritée par valeur et non par référence. C'est pourquoi, read ne vous embêtez pas avec l'entrée d'un pipe - il pas défini.

Pour info, http://www.etalabs.net/sh_tricks.html est une chouette collection de trucs nécessaires pour lutter contre les bizarreries et les incompatibilités de la bourne, de coquillages, de poissons.

118voto

Nick Points 881

si vous voulez le lire dans beaucoup de données et de travailler sur chaque ligne séparément, vous pouvez utiliser quelque chose comme ceci:

cat myFile | while read x ; do echo $x ; done

si vous voulez couper les lignes en plusieurs mots, vous pouvez utiliser plusieurs variables à la place de x comme ceci:

cat myFile | while read x y ; do echo $y $x ; done

sinon:

while read x y ; do echo $y $x ; done < myFile

Mais dès que vous commencez à vouloir faire quelque chose de vraiment à l'aise avec ce genre de chose, vous êtes mieux d'aller pour certains langage de script comme perl, où vous pouvez essayer quelque chose comme ceci:

perl -ane 'print "$F[0]\n"' < myFile

Il y a une pente assez raide de la courbe d'apprentissage avec perl (ou je suppose que l'une de ces langues), mais vous trouverez qu'il est beaucoup plus facile dans le long terme, si vous voulez faire quelque chose, mais le plus simple de scripts. Je recommanderais le Perl livre de cuisine et, bien sûr, Le Langage de Programmation Perl par Larry Wall et coll.

53voto

Steven Penny Points 18523

Ceci est une autre option

 $ read test < <(echo "hello world")

$ echo $test
hello world
 

45voto

Dennis Williamson Points 105818

read ne lira pas depuis un tube (ou le résultat est peut-être perdu car le tube crée un sous-shell). Vous pouvez cependant utiliser une chaîne ici dans Bash:

 $ read a b c <<< $(echo 1 2 3)
$ echo $a $b $c
1 2 3
 

42voto

djanowski Points 533

Je ne suis pas expert en Bash, mais je me demande pourquoi cela n'a pas été proposé:

 stdin=$(cat)

echo "$stdin"
 

Preuve unique que cela fonctionne pour moi:

 $ fortune | eval 'stdin=$(cat); echo "$stdin"'
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X