Est-il un “goto” déclaration en bash?
Est-il un "goto" déclaration en bash ? Je sais que C'est considéré comme une mauvaise pratique, mais j'ai besoin de spécifiquement "goto".
- Non, il n'y a pas
goto
en bash (au moins, il ditcommand not found
pour moi). Pourquoi? Les Chances sont, il existe une meilleure façon de le faire. - Vous n'avez jamais besoin goto, au pire, vous avez besoin de plus de pratique avec d'autres flux de contrôle des outils.
- Il peut avoir ses raisons. J'ai trouvé cette question parce que je veux un
goto
déclaration de sauter sur un grand nombre de code pour le débogage d'une grande script sans attendre une heure pour divers sans lien avec les tâches à effectuer. Je serais certainement pas utiliser ungoto
dans le code de production, mais pour le débogage mon code, ça serait ma vie infiniment plus facile, et il serait plus facile à repérer quand il est venu pour l'enlever. - Mais n'ayant pas de goto peut rendre certaines choses plus compliquées. Il y a en effet des cas d'utilisation.
- Il serait utile si vous spécifiez la raison de votre besoin. Si c'est pour la gestion des exceptions, de créer une fonction avec un rapport de sortie en elle et appeler cette fonction... Aussi, si vous avez une grande script avec beaucoup de niveaux de débogage, si ce serait beaucoup plus lisible avec une instruction if ou de le diviser en plusieurs fonctions. Ce n'est pas une bonne idée de créer des scripts Bash qui sont des centaines de lignes de long sans le fractionner en plusieurs fonctions, comme n'importe quel autre langage de programmation.
- Je le veux pour le debugging. Nous ne se soucient pas des meilleures pratiques pendant le débogage du code.
- Je suis malade de cette goto mythe! Il n'y a rien de mal avec goto! Tout ce que vous écrivez devient finalement goto. En assembleur, il y a seulement goto. Une bonne raison pour utiliser goto en plus des langages de programmation est par exemple de sauter hors de boucles imbriquées dans un endroit propre et lisible.
- Désolé, mais pas de saut de boucles imbriquées est exactement l'une des raisons pour laquelle beaucoup de gens détestent goto! Il existe des cas d'utilisation pour elle, mais ce n'est pas l'un d'eux, et même s'il l'était, ce ne serait qu'une raison d'avoir un multi-niveau continuer états; pas généralisée goto. Toujours, vous avez raison - et je suis d'accord avec votre conclusion, même si c'est pas votre exemple.
- J'ai la pire raison de tous - le portage de windows cmd fichiers de plus en plus-ou-moins de 1:1 à bash. Ils ont généralement peu à zéro de la structuration, sauf sur le "goto" niveau...
- "Éviter goto" est une grande règle. Comme toute règle, il devrait être appris en trois phases. Première: suivre la règle jusqu'à ce qu'il est une seconde nature. Deuxièmement, apprenez à comprendre les raisons de la règle. Troisièmement, apprendre les bonnes exceptions à la règle, basée sur une compréhension approfondie de la façon de suivre la règle et les motifs de la règle. Évitez de sauter des étapes ci-dessus, qui serait comme l'utilisation de "goto". 😉
- Le shell utilisé pour avoir un
goto
de commande. Le:
de commande qui sert à fabriquer une étiquette est un rudiment de ce. Toutefois, cette fonctionnalité reste aujourd'hui. - Je pense que nous avons découvert le problème. GOTO a été omis de la coquille. À qui pouvons-nous obtenir de réparer cet oubli?
Vous devez vous connecter pour publier un commentaire.
Non, il n'est pas; voir §3.2.4 "Composé de Commandes" dans le Bash Manuel de Référence pour plus d'informations sur les structures de contrôle qui ne existent. En particulier, la note de la mention de
break
etcontinue
, qui ne sont pas aussi flexibles quegoto
, mais sont plus souples dans Bash que dans certaines langues, et peut vous aider à obtenir ce que vous voulez. (Tout ce que vous voulez . . .)break
oucontinue
du plus intime de la boucle, alors que Bash permet de spécifier le nombre de niveaux de boucle pour sauter. (Et même des langues qui vous permettent debreak
oucontinue
de l'arbitraire des boucles, mais la plupart exigent que, pour être exprimé de manière statique (par exemple,break foo;
va sortir de la boucle marquéfoo
, alors qu'en Bash c'est exprimé de façon dynamique -- par exemple,break "$foo"
va sortir de$foo
boucles.)Si vous l'utilisez pour sauter une partie d'une grande script de débogage (voir Karl Nicoll du commentaire), puis si le faux peut être une bonne option (je ne sais pas si "false" est toujours disponible, pour moi, c'est dans /bin/false):
La difficulté vient quand il est temps d'arracher le débogage de code. La "si la valeur est false" construire, c'est assez simple et mémorable, mais comment voulez-vous trouver la correspondance fi? Si votre éditeur vous permet de bloquer tiret, vous pourriez mettre en retrait le sauté de bloc (alors vous aurez envie de le remettre lorsque vous avez terminé). Ou un commentaire sur la fi gratuite ligne, mais il devrait être quelque chose que vous vous en souvenez, ce qui je pense sera très programmeur-dépendante.
false
est toujours disponible. Mais si vous avez un bloc de code, vous ne voulez pas exécuter, juste en commentaire. Ou de le supprimer (et de regarder dans votre système de contrôle de source si vous avez besoin de le récupérer plus tard).En effet, elle peut être utile pour certains de débogage ou de démonstration besoins.
J'ai trouvé que Bob Copeland solution http://bobcopeland.com/blog/2012/10/goto-in-bash/ élégant:
résultats dans:
: start:
sorte qu'ils ne sont pas des erreurs de syntaxe.set -x
permet de comprendre ce qu'il se passe:
. 2) Traitelabel:
n'importe où sur une ligne comme étiquette. Voir ici pour la résolution.Vous pouvez utiliser
case
en bash pour simuler un goto:produit:
bash v4.0+
. Il est, cependant, pas d'un usage généralgoto
mais une chute-par le biais de l'option pour lecase
déclaration.Si vous faites des tests/débogage d'un script bash, et veulent simplement sauter passé une ou plusieurs sections de code, voici un moyen très simple de faire ce qui est également très facile de trouver et de supprimer plus tard (contrairement à la plupart des méthodes décrites ci-dessus).
De mettre votre script de retour à la normale, il suffit de supprimer toutes les lignes avec
GOTO
.On peut aussi embellir cette solution, en ajoutant un
goto
de commande comme un alias:Alias n'avez pas l'habitude de travailler dans des scripts bash, donc nous avons besoin de la
shopt
de commande pour résoudre ce problème.Si vous voulez être en mesure d'activer/de désactiver votre
goto
's, nous avons besoin d'un peu plus:Ensuite, vous pouvez faire
export DEBUG=TRUE
avant d'exécuter le script.Les étiquettes sont des commentaires, afin de ne pas causer des erreurs de syntaxe si vous désactivez nos
goto
's (par la mise engoto
à la":
" no-op), mais cela signifie que nous avons besoin de les citer dans notregoto
consolidés.Lors de l'utilisation de tout type de
goto
solution, vous devez être attentif à ce que le code que vous avez à sauter le passé n'a pas d'ensemble de toutes les variables que vous compter sur plus tard vous pouvez avoir besoin de déplacer ces définitions en haut de votre script, ou juste au-dessus de l'un de vosgoto
consolidés.if(false)
semble plus logique (pour moi).alias goto=":<<"
et de renoncer auxcat
tout à fait.Bien que d'autres l'ont déjà précisé qu'il n'y a pas de direct
goto
équivalent en bash (et à condition que la plus proche des alternatives telles que les fonctions, les boucles et la pause), je voudrais illustrer comment l'utilisation d'une boucle plusbreak
peut simuler un type spécifique d'instruction goto.La situation où je peux trouver, c'est la plus utile, c'est quand j'ai besoin de revenir au début d'une section de code que si certaines conditions ne sont pas remplies. Dans l'exemple ci-dessous, la boucle while s'exécute indéfiniment jusqu'à ce que le ping cesse de déposer des paquets à un test d'IP.
Il y a une plus grande capacité à atteindre les résultats souhaités: commande
trap
. Il peut être utilisé pour le nettoyage par exemple.Il n'y a pas de
goto
en bash.Voici quelques sale solution de contournement à l'aide de
piège
qui saute uniquement vers l'arrière:)De sortie:
Ce ne doit pas être utilisé de cette façon, mais seulement pour des fins éducatives. Ici, c'est pourquoi cela fonctionne:
trap
est à l'aide de la gestion des exceptions pour atteindre le changement dans le flux de code.Dans ce cas, le
trap
est la capture de tout ce qui provoque le script de SORTIE. La commandegoto
n'existe pas, et donc renvoie une erreur, ce qui serait normalement quitter le script. Cette erreur est d'être pris avectrap
, et la2>/dev/null
masque le message d'erreur qui serait normalement affiché.Cette mise en œuvre de goto n'est évidemment pas fiable, car tout inexistante de commande (ou de toute autre erreur, de cette manière), exécuter la même commande de piège. En particulier, vous ne pouvez pas choisir le type d'étiquette à aller à.
Fondamentalement dans le réel scénario, vous n'avez pas besoin d'instructions goto, ils sont redondants comme aléatoire des appels à différents endroits seulement de rendre votre code difficile à comprendre.
Si votre code est invoqué à de nombreuses reprises, alors envisager d'utiliser la boucle et l'évolution de ses flux de travail à utiliser
continue
etbreak
.Si votre code se répète, considérer l'écriture de la fonction et de l'appeler autant de fois que vous le souhaitez.
Si votre code doit sauter dans la section spécifique basé sur la valeur de la variable, alors envisager l'utilisation de
case
déclaration.Si vous pouvez séparer votre long code en morceaux plus petits, pensez à la placer dans des fichiers séparés et de les appeler dans le script parent.
trap
que l'utilisation deexception handling
d'atteindre le changement dans le flux de code. Dans ce cas, le piège est d'attraper tout ce qui provoque le script pourEXIT
, qui est déclenché par l'invocation de l'inexistant commandegoto
. BTW: L'argumentgoto trap
pourrait être n'importe quoi,goto ignored
parce que c'est lagoto
qui provoque la SORTIE, et la2>/dev/null
masque le message d'erreur indiquant que votre script est sortie.Cette solution eu les problèmes suivants:
:
label:
n'importe où sur une ligne comme étiquetteVoici un fixe (
shell case
propre) version:C'est une petite correction de l'Judy Schmidt scénario mis en place par Hubbbitus.
En mettant des caractères d'échappement d'étiquettes dans le script était problématique sur la machine et qui ont provoqué le crash. C'était assez facile à résoudre en ajoutant # pour échapper aux étiquettes. Grâce à Alexej Magura et access_granted pour leurs suggestions.
jumpto $start
Un simple consultable goto pour l'utilisation de commenter le code des blocs lors du débogage.
Résultat est-> GOTO fait
J'ai trouvé un moyen de faire cela à l'aide de fonctions.
Dire, par exemple, vous avez 3 choix:
A
,B
, etC
.A
etB
exécuter une commande, maisC
vous donne plus d'infos et vous emmène à l'origine de l'invite de nouveau. Cela peut être fait à l'aide de fonctions.Noter que, depuis la ligne contenant
function demoFunction
est tout simplement la mise en place de la fonction, vous devez appelerdemoFunction
après que le script de sorte que la fonction sera exécuté.Vous pouvez facilement adapter ce par l'écriture de plusieurs autres fonctions et de les appeler si vous avez besoin de "
GOTO
" un autre place dans votre script shell.