Comment utiliser la commande read en Bash?
Lorsque j'essaie d'utiliser le read
commande de Bash comme ceci:
echo hello | read str
echo $str
Nothing otherwise, while I think str
devrait contenir la chaîne hello
. Quelqu'un peut-il m'aider à comprendre ce comportement?
8 réponses
read
dans votre script, la commande est correcte. Cependant, vous l'exécutez dans le pipeline, ce qui signifie qu'il est dans un sous-puits, donc les variables qu'il lit ne sont pas visibles dans le shell parent. Vous pouvez soit
déplacer le reste du script en shell interne est exécuté, trop:
echo hello | { read str echo $str }
ou utilisez la substitution de commande pour obtenir la valeur de la variable hors de la sous-cellule
str=$(echo hello) echo $str
str=$(ls | { read a; read a; echo $a; }) echo $str
autres alternatives bash qui n'impliquent pas de sous-couche:
read str <<END # here-doc
hello
END
read str <<< "hello" # here-string
read str < <(echo hello) # process substitution
L'usage typique peut ressembler à:
i=0
echo -e "hello1\nhello2\nhello3" | while read str ; do
echo "$((++i)): $str"
done
et de sortie
1: hello1
2: hello2
3: hello3
la valeur disparaît puisque la commande read est exécutée dans un sous-puits séparé: Bash FAQ 24
Pour mettre mon grain de sel ici: sur KSH, read
ing est à une variable travailler, parce que selon AIX IBM documentation, KSH's read
affecte l'environnement shell actuel:
le paramétrage des variables shell par la commande read affecte l'environnement actuel d'exécution du shell.
cela m'a juste amené à passer quelques bonnes minutes à comprendre pourquoi un one-liner se terminant par read
que j'ai utilisé un zillion de fois sur AIX n'a pas fonctionné sur Linux... C'est parce que KSH sauve à L'environnement actuel et que BASH ne le fait pas!
je n'ai vraiment lire avec "tout" et une boucle:
echo "This is NOT a test." | while read -r a b c theRest; do
echo "$a" "$b" "$theRest"; done
Ceci est un test.
Pour ce que ça vaut, j'ai vu la recommandation d'utiliser toujours-r avec la commande read en bash.
une autre alternative consiste à utiliser la fonction printf.
printf -v str 'hello'
de plus, Cette construction, combinée avec l'utilisation de guillemets simples le cas échéant, aide à éviter les problèmes de multi-escape de subshells et d'autres formes de citation interpolative.