Je suis tombé sur ce problème intéressant en remplissant ma barre WM avec du texte d'informations, qui est appliqué en définissant le titre de la fenêtre racine, c'est-à-dire xsetroot -name "clever words"
À cette fin, l'impression d'une fortune fonctionne très bien dans un terminal:
fortune -s | while read -r; do xsetroot -name "$REPLY"; done
Pourtant, ce même échoue lorsqu'il est exécuté à partir d'un script shell:
#!/bin/sh
cat /tmp/afile | while read; do echo "$REPLY"; done
Produit:
$ sh afilereader
afilereader: 2: read: arg count
Bien sûr, cela est résolu en affectant notre résultat de fortune à une variable, puis en utilisant xsetroot avec ladite variable. Mais j'aimerais quand même comprendre pourquoi cela ne fonctionne pas dans un script.
Je me rends compte que chaque commande de chaque côté du pipeline est exécutée dans son propre sous-shell, mais je ne vois pas comment leurs variables localisées pourraient affecter la boucle de lecture while. Ou les variables sont-elles hors de portée, même entre les itérations de boucle?
Qu'est-ce que je rate?
Mise à jour: le que sh
j'ai utilisé est lié au tiret, qui est en cours de mise en conformité POSIX. L'utilisation du plus vénérable a bash
résolu ce problème.
la source
read
être invocable sans variable: pubs.opengroup.org/onlinepubs/9699919799/utilities/read.htmlRéponses:
Vous semblez exécuter le premier exemple dans
bash
, et le second dans tout ce qui est indiqué par/bin/sh
, qui est un shell POSIX nécessitant un argument à passer spécifiant la variable dans laquelle vous souhaitez mettre l'entrée. Changer le shebang en#!/bin/bash
devrait résoudre ce problème.la source
sh
etbash
./bin/sh
à bash, mais je pense que j'utiliserais bash directement à partir de maintenant, pour éviter toute ambiguïté. Merci :)Dans la syntaxe sh, vous avez besoin
Certains shells comme ksh, bash et zsh permettent
read
d'être appelés sans nom de variable mais le comportement diffère entre eux. Voir par exemple la sortie dedifférent sur tous les bash, zsh, pdksh et ksh93
la source