web-dev-qa-db-fra.com

La barre de progression de Zenity affecte-t-elle les variables?

Salut les gars, je suis en train d’essayer d’implémenter la barre de progression zenity dans ma boucle while. Cependant, j’ai remarqué que mes variables qui étaient censées être incrémentées n’augmentaient pas. Voici un exemple de script de test que j'ai essayé:

i=0
p=0

while [ $i -lt 10 ]
do
      i=$[$i + 1]
      echo $i
      p=$[$p + 1]
done | (zenity --progress --title="test" --text="test")
echo "i: $i p: $p"

J'ai remarqué que la barre de progression fonctionnait, mais la variable p qui est censée être un compteur était affectée par le zenity. Y at-il quelque chose qui ne va pas avec mon code? la variable i est censée faire écho à la valeur afin de déplacer la barre de progression, tandis que la variable p sert à d’autres fins. Les valeurs de p et i sont toutes deux 0 même si elles sont incrémentées dans la boucle while.

J'espère qu'il est possible de faire en sorte que la variable p et i s'incrémente sans supprimer la barre de progression de zenity. Je ne sais pas pourquoi, cependant, l'incrémentation des variables fonctionne après la suppression de la ligne (zenity --progress --title="test" --text="test")

Ajout

Comment utiliser les variables i et p après la fin de la barre de progression? Et une autre question, est-il nécessaire de joindre la boucle while avec ()?

Merci pour toute aide!

2
pikachu

Incrément et tout semble aller pour le mieux. Mais tous les incréments ont lieu dans un sous-shell qui est passé à zenity. C'est la raison pour laquelle vous n'obtenez pas les modifications lorsque vous echo en dehors du sous-shell. J'utilise votre script, ajoutant seulement quelque chose pour imprimer les variables à l'intérieur de la boucle do while sur la fenêtre contextuelle zenity. Pour en savoir plus sur la syntaxe de la boîte de dialogue de progression de zenity, voir page d'aide de gnome . Exécutez le script ci-dessous et voyez le résultat,

#!/bin/bash
i=0
p=0
(while [ $i -lt 100 ]
do
    i=$[$i + 10]
    echo $i ; sleep 1
    echo "#  now i is $i and p=$p"
    p=$[$p + 1]
done) | zenity --progress --title="test" --text="test"
echo "i: $i p: $p"

J'ai changé l'incrément de i en 10 comme i sera utilisé pour rendre l'incrément de barre de progression et utilisé sleep 1 pour rendre la progression perceptible.

Observation: Bien que la valeur affichée soit incrémentée dans la fenêtre contextuelle zenity. Il montre pour être inchangé sur le terminal, i: 0 p: 0

the zenity window

J'espère que cela serait utile.

Comment utiliser des variables de sous-shell en dehors de

Le Shell parent ne peut pas utiliser de variables de son sous-shell. Vous pouvez trouver plus d'informations sur le sous-shell ici . Mais vous pouvez toujours écrire des variables du sous-shell dans un fichier temporaire que son parent lira. Ce n'est peut-être pas le meilleur des moyens, mais cela fonctionne.

#!/bin/bash
..
(while [ $i -lt 100 ]
do
    ...
    ...
done
echo "p=$(echo $p)" > tmp
echo "i=$(echo $i)" >> tmp
) | zenity --progress --title="test" --text="test"
. tmp
rm tmp
echo "i: $i p: $p"

Maintenant, il apparaîtra dans le terminal comme, i: 100 p: 10 afin que vous puissiez les utiliser à votre guise. Et comme vous l’avez demandé dans la dernière partie, ce n’est pas la boucle while, c’est un sous-shell. Il est de coutume de placer le contenu du sous-shell entre parenthèses.

3
souravc

La substitution de processus peut empêcher la création de sous-shell gênants, mais la syntaxe est un peu bizarre:

$ k=0; for x in a b; do ((k++)); done | zenity --progress; echo "$k"

→ 0 (Pas OK)

$ k=0; for x in a b; do ((k++)); done > >(zenity --progress); echo "$k"

→ 2 (OK)

Ce qui me plaît dans cette situation, c’est que vous n’avez généralement pas à modifier votre script pour qu’il fonctionne correctement. Cependant, certains coquillages exotiques pourraient manquer de cette fonctionnalité. Pour Bash, consultez la section "Process Substitution" du processus.

Avec un code plus proche de l'exemple de la question initiale:

  i=0
  p=0

  while [ $i -lt 10 ]
  do
        i=$[$i + 1]
        echo $((10 * i))
        sleep 0.1
        p=$[$p + 1]
  done > >(zenity --progress --title="test" --text="test")
  echo "i: $i p: $p"

(J'ai ajouté un sommeil pour rendre la progression plus visible, et je répète dix fois i d'avoir un 100 lorsque j'atteins la fin de la boucle.)

1
Alice M.