web-dev-qa-db-fra.com

En bash, comment définir un code retour?

Je veux définir une valeur de retour une fois pour qu'elle entre dans la boucle while:

#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0    
done

Pour que cela fonctionne, je dois définir $? = 1 au début, mais cela ne fonctionne pas.

25
JohnnyFromBF
#!/bin/bash

RC=1

while [ $RC -eq 1 ]
do

  #do something until it returns 0    

  RC=$?
done
11
Eugen Rieck

Vous pouvez définir un code de sortie arbitraire en exécutant exit avec un argument dans un sous-shell.

$ (exit 42); echo "$?"
42

Vous pourriez donc faire:

(exit 1)    # or some other value > 0 or use false as others have suggested
while (($?))
do
    # do something until it returns 0    
done

Ou vous pouvez émuler un do while boucle :

while 
    # do some stuff
    # do some more stuff
    # do something until it returns 0    
do
    continue  # just let the body of the while be a no-op
done

L'un ou l'autre garantit que la boucle est exécutée au moins une fois, ce qui est, je crois, votre objectif.

Pour être complet, exit et return acceptent chacun un argument facultatif qui est un entier (positif, négatif ou zéro) qui définit le code retour comme le reste de l'entier après division par 256. Le courant Shell (ou script ou sous-shell *) se ferme en utilisant exit et une fonction se ferme en utilisant return.

Exemples:

$ (exit -2); echo "$?"
254
$ foo () { return 2000; }; foo; echo $?
208

* Cela est vrai même pour les sous-coquilles créées par des canaux (sauf lorsque le contrôle des travaux est désactivé et que lastpipe est activé):

$ echo foo | while read -r s; do echo "$s"; exit 333; done; echo "$?"
77

Notez qu'il vaut mieux utiliser break pour laisser des boucles, mais son argument est pour le nombre de niveaux de boucles à sortir plutôt que pour un code retour.

Le contrôle des travaux est désactivé à l'aide de set +m, set +o monitor ou shopt -u -o monitor. Pour activer lastpipe do shopt -s laspipe. Si vous faites les deux, le exit dans l'exemple précédent provoquera la boucle while et le shell contenant pour la sortie et la dernière echo il ne sera pas effectuée.

107

false renvoie toujours un code de sortie de 1.

#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0    
done
17
chepner

Certaines réponses reposent sur la réécriture du code. Dans certains cas, il peut s'agir d'un code étranger sur lequel vous n'avez aucun contrôle.

Bien que pour cette question spécifique, il suffit de définir $? à 1, mais si vous devez définir $? à toute valeur - la seule réponse utile est celle de Dennis Williamson.

Une approche un peu plus efficace, qui ne donne pas naissance à un nouvel enfant (mais est également moins laconique), est la suivante:

function false() { echo "$$"; return ${1:-1}; }
false 42

Remarque: la partie d'écho est là juste pour vérifier qu'elle fonctionne dans le processus actuel.

6
chukko

N'a rien trouvé de plus léger qu'une simple fonction:

function set_return() { return ${1:-0}; }

Toutes les autres solutions comme (...) ou [...] ou false peut contenir un appel de processus externe.

1
Andry

Vieille question, mais il y a une bien meilleure réponse:

#!/bin/bash
until
    #do something until it returns success
do
    :;
done

Si vous bouclez jusqu'à ce que quelque chose réussisse, faites-le simplement dans la section jusqu'à. Vous pouvez mettre exactement le même code dans la section jusqu'à ce que vous pensiez devoir mettre dans la section do/done. Vous n'êtes pas obligé d'écrire le code dans la section do/done, puis de retransférer ses résultats dans le temps ou jusqu'à ce que.

1
don provan

Est-ce que quelque chose comme ça serait ce que vous cherchez?

#!/bin/bash
TEMPVAR=1
while [ $TEMPVAR -eq 1 ]
do
  #do something until it returns 0
  #construct the logic which will cause TEMPVAR to be set 0 then check for it in the 
  #if statement 

  if [ yourcodehere ]; then
     $TEMPVAR=0
  fi
done
1
David K

Vous pouvez utiliser until pour gérer les cas où #do something until it returns 0 renvoie autre chose que 1 ou 0:

#!/bin/bash

false
until [ $? -eq 0 ]
do
#do something until it returns 0    
done
0
Steven Kearnes