Incrémenter une variable globale dans Bash
Voici un script shell:
globvar=0
function myfunc {
let globvar=globvar+1
echo "myfunc: $globvar"
}
myfunc
echo "something" | myfunc
echo "Global: $globvar"
Lorsqu'il est appelé, il imprime le suivant:
$ sh zzz.sh
myfunc: 1
myfunc: 2
Global: 1
$ bash zzz.sh
myfunc: 1
myfunc: 2
Global: 1
$ zsh zzz.sh
myfunc: 1
myfunc: 2
Global: 2
La question est: pourquoi ce qui se passe et ce comportement est correct?
P. S. j'ai l'étrange impression que la fonction derrière la pipe est appelée dans une fourche shell... Donc, peut-il y avoir une solution simple?
P. P. S. Cette fonction est un simple test wrapper. Il s'exécute en application de test et d'analyse de sa sortie. Puis il incrémente $PASSÉ ou $a ÉCHOUÉ variables. Enfin, vous obtenez un certain nombre de réussi/échoué des tests dans des variables globales. L'utilisation est comme:
test-util << EOF | myfunc
input for test #1
EOF
test-util << EOF | myfunc
input for test #2
EOF
echo "Passed: $PASSED, failed: $FAILED"
Avez-vous lu: tldp.org/LDP/abs/html/localvar.html ?
eh bien, à mon avis $globvar n'est pas une variable locale, parce que l'appel de mafonction() sans tuyau incrémente la variable globale $globvar assez bien. Le problème, c'est que l'appel de la fonction sur la pipe ne fonctionne pas en bash/sh.
eh bien, à mon avis $globvar n'est pas une variable locale, parce que l'appel de mafonction() sans tuyau incrémente la variable globale $globvar assez bien. Le problème, c'est que l'appel de la fonction sur la pipe ne fonctionne pas en bash/sh.
OriginalL'auteur zserge | 2010-11-23
Vous devez vous connecter pour publier un commentaire.
Korn shell donne les mêmes résultats que zsh, par la manière.
Veuillez voir BashFAQ/024. Les tuyaux de créer des sous-coquille en Bash et les variables sont perdues lors de la sous-coquille de sortie.
Basé sur votre exemple, je voudrais réorganiser quelque chose comme ceci:
Un autre moyen serait comme ceci:
myfunc() { echo "two words"; }; read word1 word2 <<< $(myfunc)
ouarray=($(myfunc))
.OriginalL'auteur Dennis Williamson
Tuyauterie quelque chose dans
myfunc
danssh
oubash
provoque un nouveau shell pour frayer. Vous pouvez le vérifier par l'ajout d'un long sommeil dansmyfunc
. Alors qu'il dort appel ps et vous verrez un sous-processus. Lorsque la fonction retourne une valeur, qui sous-shell sorties sans modification de la valeur dans le processus parent.Si vous avez vraiment besoin de cette valeur pour être changé, vous devrez retourner une valeur de la fonction et vérifier les $PIPESTATUS après, je suppose que, comme ceci:
PIPESTATUS
avant.Le seul problème avec cette technique est que votre valeur de retour doit être dans la gamme de 0 à 255.
OriginalL'auteur mkb
Le problème est l'extrémité d'une canalisation à l'aide de built-ins est exécuté par le processus d'origine?'
Dans zsh, il semble que la dernière commande dans le pipeline est exécuté par le shell principal de script lorsque la commande est une fonction intégrée ou d'.
En Bash (et le poisson est susceptible d'être un lien vers Bash si vous êtes sur Linux), puis les deux commandes sont exécutées dans un sous-shell ou la première commande est exécutée par le processus principal et les autres sont dirigés par des sous-shells.
Clairement, lorsque la fonction est exécutée dans un sous-shell, elle ne modifie pas la variable dans le shell parent (uniquement le mondial dans la sous-shell).
Envisager d'ajouter un test supplémentaire:
OriginalL'auteur Jonathan Leffler
Utilisation
export
au lieu delet
, sinon la variable est locale(utiliser $(()) ainsi que de faire des opérations arithmétiques)
mon erreur, je ne vois pas le problème. Pourquoi avez-vous besoin d'appeler un nouveau shell plutôt que de simplement appeler le script ?
En fait, je n'ai pas. J'ai juste besoin de rediriger une sortie de programme de test de la fonction shell pour savoir si le test a réussi. Une manière claire de redirection de la sortie est une pipe, mais la pipe fourches d'un sous-shell.
OriginalL'auteur mb14