Au travail, jécris fréquemment des scripts bash. Mon superviseur a suggéré que le script entier soit divisé en fonctions, similaires à lexemple suivant:
#!/bin/bash # Configure variables declare_variables() { noun=geese count=three } # Announce something i_am_foo() { echo "I am foo" sleep 0.5 echo "hear me roar!" } # Tell a joke walk_into_bar() { echo "So these ${count} ${noun} walk into a bar..." } # Emulate a pendulum clock for a bit do_baz() { for i in {1..6}; do expr $i % 2 >/dev/null && echo "tick" || echo "tock" sleep 1 done } # Establish run order main() { declare_variables i_am_foo walk_into_bar do_baz } main
Y a-t-il une raison de faire cela autre que la « lisibilité » , qui, je pense, pourrait être tout aussi bien établi avec quelques commentaires supplémentaires et quelques interlignes?
Est-ce que cela rend le script plus efficace (je mattendrais en fait au contraire, le cas échéant), ou est-ce que cela fait il est plus facile de modifier le code au-delà du potentiel de lisibilité mentionné ci-dessus? Ou est-ce vraiment juste une préférence stylistique?
Veuillez noter que bien que le script ne le montre pas bien, l « ordre dexécution » des fonctions dans nos scripts réels a tendance à être très linéaire – walk_into_bar
dépend de ce que i_am_foo
a fait, et do_baz
agit sur les éléments configurés par walk_into_bar
– donc être capable de permuter arbitrairement lordre dexécution nest pas quelque chose que nous ferions généralement. Par exemple, vous ne voudriez pas soudainement mettre declare_variables
après walk_into_bar
, cela casserait les choses.
Un exemple de la façon dont jécrirais le script ci-dessus serait:
#!/bin/bash # Configure variables noun=geese count=three # Announce something echo "I am foo" sleep 0.5 echo "hear me roar!" # Tell a joke echo "So these ${count} ${noun} walk into a bar..." # Emulate a pendulum clock for a bit for i in {1..6}; do expr $i % 2 >/dev/null && echo "tick" || echo "tock" sleep 1 done
Commentaires
Answer
Jai commencé à utiliser ce même style de programmation bash après avoir lu le billet de blog de Kfir Lavi « Defensive Bash Programming » . Il donne pas mal de bonnes raisons, mais personnellement je trouve celles-ci les plus importantes:
-
les procédures deviennent descriptives: il est beaucoup plus facile de comprendre ce quune partie particulière du code est supposée à faire. Au lieu dun mur de code, vous voyez « Oh, la fonction
find_log_errors
lit ce fichier journal pour les erreurs ». Comparez-le avec la recherche dun grand nombre de lignes awk / grep / sed qui utiliser Dieu sait quel type de regex au milieu dun long script – vous navez aucune idée de ce quil fait là-bas à moins quil y ait des commentaires. -
vous pouvez déboguer des fonctions en englobant
set -x
etset +x
. Une fois que vous savez que le reste du code fonctionne correctement, vous pouvez utiliser cette astuce pour vous concentrer uniquement sur le débogage de cette fonction spécifique. Bien sûr, vous pouvez inclure des parties du script, mais que se passe-t-il si cest « une longue partie? Il est plus facile de faire quelque chose comme ceci:set -x parse_process_list set +x
-
utilisation de limpression avec
cat <<- EOF . . . EOF
. Je lai utilisé plusieurs fois pour rendre mon code beaucoup plus professionnel. De plus, la fonctionparse_args()
avecgetopts
est assez pratique. Encore une fois, cela aide à la lisibilité, au lieu de tout pousser dans le script comme un mur géant de texte. Il est également pratique de les réutiliser.
Et évidemment, cest beaucoup plus lisible pour quelquun qui connaît C ou Java, ou Vala, mais qui a une expérience limitée en bash. En ce qui concerne lefficacité, il ny a pas grand-chose à faire – bash lui-même nest pas le langage le plus efficace et les gens préfèrent perl et python en termes de rapidité et defficacité.Cependant, vous pouvez nice
une fonction:
nice -10 resource_hungry_function
Par rapport à appeler nice sur chaque ligne de code, cela diminue beaucoup de frappe ET peut être utilisé de manière pratique lorsque vous ne voulez quune partie de votre script sexécute avec une priorité inférieure.
Exécuter des fonctions en arrière-plan, à mon avis, aide également lorsque vous voulez avoir tout tas dinstructions à exécuter en arrière-plan.
Quelques exemples où jai utilisé ce style:
- https://askubuntu.com/a/758339/295286
- https://askubuntu.com/a/788654/295286
- https://github.com/SergKolo/sergrep/blob/master/chgreeterbg.sh
Commentaires
- Je ne suis pas sûr que vous deviez prendre les suggestions de cet article très au sérieux. Certes, il a quelques bonnes idées, mais ce nest clairement pas quelquun qui est habitué aux scripts shell. Pas un une seule variable dans lun des exemples est citée (!) et suggère dutiliser UPPER C Les noms de variables ASE, ce qui est souvent une très mauvaise idée car ils peuvent entrer en conflit avec les variables denvironnement existantes. Vos remarques dans cette réponse ont du sens, mais larticle lié semble avoir été écrit par quelquun qui est juste habitué à dautres langues et essaie de forcer son style à bash.
- @terdon Je suis retourné à larticle et lai relu. Le seul endroit où lauteur mentionne la dénomination des variables en majuscules est dans » Variables globales immuables « . Si vous considérez les variables globales comme celles qui doivent être dans lenvironnement de la fonction ‘, alors il est logique de les rendre majuscules. Sur la note latérale, bash ‘ s manuel ne ‘ t convention détat pour la casse des variables. Même ici la réponse acceptée dit » généralement » et le seul » standard » est de Google, qui ne ‘ t représente l’ensemble du secteur informatique.
- @terdon sur une autre note, je suis daccord à 100% sur le fait que la citation variable aurait dû être mentionnée dans larticle, et cela a également été souligné dans les commentaires sur le blog. De plus, je ne jugerais pas ‘ quelquun qui utilise ce style de codage, quil soit ou non ‘ habitué à une autre langue. Lensemble de cette question et de ses réponses montre clairement les avantages de ‘, et le degré de ‘ auquel ils ‘ être habitué à une autre langue nest probablement pas pertinent ici.
- @terdon eh bien, larticle a été publié dans le cadre de la » source » matériel. Jaurais pu tout publier en tant que mes propres opinions, mais je devais simplement reconnaître que certaines des choses que javais apprises dans larticle et que tout cela provenait de recherches au fil du temps. La page linkedin de lauteur ‘ montre quils ont une bonne expérience avec Linux et linformatique en général, donc je ‘ d suppose que larticle ne ‘ Je le montre vraiment, mais jai confiance en votre expérience en matière de scripts Linux et shell, donc vous avez peut-être raison.
- Cest ‘ est une excellente réponse mais je ‘ d aime aussi ajouter que la portée des variables dans Bash est géniale. Pour cette raison, je préfère déclarer mes variables à lintérieur de fonctions en utilisant
local
et en appelant tout via la fonctionmain()
. Cela rend les choses beaucoup plus faciles à gérer et vous pouvez éviter une situation potentiellement désordonnée.
Réponse
La lisibilité est une chose. Mais la modularisation ne se résume pas à cela. (La semi-modularisation est peut-être plus correcte pour les fonctions.)
Dans les fonctions, vous pouvez garder certaines variables locales, ce qui augmente la fiabilité , diminuant les chances de les choses se gâtent.
Un autre avantage des fonctions est la réutilisation . Une fois quune fonction est codée, elle peut être appliquée plusieurs fois dans le script. Vous pouvez également le porter vers un autre script.
Votre code peut maintenant être linéaire, mais à lavenir, vous pouvez entrer dans le domaine du multi-threading , ou multi- traitement dans le monde Bash. Une fois que vous aurez appris à faire des choses dans les fonctions, vous serez bien équipé pour entrer dans le parallèle.
Encore un point à ajouter. Comme le remarque Etsitpab Nioliv dans le commentaire ci-dessous, il est facile de rediriger des fonctions comme une entité cohérente. Mais il y a encore un aspect des redirections avec des fonctions. À savoir, les redirections peuvent être définies le long de la définition de la fonction. Exemple:
f () { echo something; } > log
Désormais, aucune redirection explicite nest nécessaire pour les appels de fonction.
$ f
Cela peut épargner de nombreuses répétitions, ce qui augmente encore la fiabilité et aide à garder les choses en ordre.
Voir aussi
Commentaires
- Très bien réponse bien que ce serait bien mieux sil était divisé en fonctions.
- Peut-être ajouter que les fonctions vous permettent dimporter ce script dans un autre script (en utilisant
source
ou. scriptname.sh
, et utilisez ces fonctions comme si elles étaient dans votre nouveau script. - Ces ‘ sont déjà couvertes dans une autre réponse.
- Japprécie cela. Mais je ‘ laisserais plutôt dautres personnes être importantes aussi.
- Jai été confronté à un cas aujourdhui où je devais rediriger une partie de la sortie dun script vers un fichier (pour lenvoyer par e-mail) au lieu de faire écho. Je devais simplement faire myFunction > > myFile pour rediriger la sortie des fonctions souhaitées. Assez pratique. Peut être pertinent.
Réponse
Dans mon commentaire, jai mentionné trois avantages des fonctions:
-
Ils sont plus faciles à tester et à vérifier lexactitude.
-
Les fonctions peuvent être facilement réutilisées (source) dans les futurs scripts
-
Votre patron les aime bien.
Et, ne sous-estimez jamais limportance du chiffre 3.
Je voudrais aborder un autre problème:
… donc pouvoir échanger arbitrairement lordre dexécution nest pas quelque chose que nous ferions généralement. Par exemple, vous ne voudriez pas soudainement mettre
declare_variables
aprèswalk_into_bar
, cela casserait les choses.
Pour profiter de la décomposition du code en fonctions, il faut essayer de rendre les fonctions aussi indépendantes que possible. Si walk_into_bar
nécessite une variable qui nest pas utilisée ailleurs, alors cette variable doit être définie et rendue locale à walk_into_bar
. Le processus de séparation du code en fonctions et de minimisation de leurs interdépendances devrait rendre le code plus clair et plus simple .
Idéalement, les fonctions devraient être faciles à tester individuellement. Si, à cause des interactions, elles ne sont pas faciles à tester, cest un signe quelles pourraient bénéficier dune refactorisation.
Commentaires
- Je ‘ je soutiens que ‘ est parfois sensé modéliser et appliquer ces dépendances, vs refactoriser pour les éviter (car sil y a assez h dentre eux, et ils ‘ sont suffisamment velus, cela peut juste conduire à un cas où les choses ne sont plus du tout modularisées en fonctions). Un cas dutilisation très compliqué a déjà inspiré un framework pour faire exactement cela .
- Ce qui doit être divisé en fonctions devrait lêtre, mais lexemple va trop loin. Je pense que le seul qui me dérange vraiment est la fonction de déclaration de variable. Les variables globales, en particulier les variables statiques, doivent être définies globalement dans une section commentée dédiée à cet effet. Les variables dynamiques doivent être locales aux fonctions qui les utilisent et les modifient.
- @Xalorous Jai ‘ vu une pratique où les variables globales sont initialisées dans une procédure, comme étape intermédiaire et rapide avant le développement dune procédure qui lit leur valeur à partir dun fichier externe … je conviens quil devrait être plus propre de séparer la définition et linitialisation mais rarement il faut se plier pour subir le avantage numéro 3
;-)
Réponse
Bien que je sois tout à fait daccord avec la réutilisabilité , la lisibilité , et embrasser délicatement les patrons mais il y a un autre avantage des fonctions dans bash : portée de la variable . Comme le montre LDP :
#!/bin/bash # ex62.sh: Global and local variables inside a function. func () { local loc_var=23 # Declared as local variable. echo # Uses the "local" builtin. echo "\"loc_var\" in function = $loc_var" global_var=999 # Not declared as local. # Therefore, defaults to global. echo "\"global_var\" in function = $global_var" } func # Now, to see if local variable "loc_var" exists outside the function. echo echo "\"loc_var\" outside function = $loc_var" # $loc_var outside function = # No, $loc_var not visible globally. echo "\"global_var\" outside function = $global_var" # $global_var outside function = 999 # $global_var is visible globally. echo exit 0 # In contrast to C, a Bash variable declared inside a function #+ is local ONLY if declared as such.
Je ne vois pas cela très souvent dans le monde réel des scripts shell, mais cela semble être une bonne idée pour les scripts plus complexes. La réduction de la cohésion permet d’éviter les bogues où vous « corrigez une variable attendue dans une autre partie du code .
La réutilisation signifie souvent la création dune bibliothèque commune de fonctions et source
ing cette bibliothèque dans tous vos scripts. Cela ne les aidera pas à fonctionner plus vite, mais cela vous aidera à les écrire plus rapidement.
Commentaires
- Peu de gens utilisent explicitement
local
, mais je pense que la plupart des gens qui écrivent des scripts décomposés en fonctions suivent toujours le principe de conception. Usignlocal
rend simplement plus difficile lintroduction de bogues. -
local
rend les variables disponibles pour la fonction et ses enfants, donc ‘ est vraiment agréable davoir une variable qui peut être transmise en bas de la fonction A, mais non disponible pour la fonction B, qui peut vouloir avoir une variable avec le même nom mais un but différent.Pour que ‘ soit bon pour définir la portée, et comme Voo la dit – moins de bogues
Réponse
Vous divisez le code en fonctions pour la même raison que vous le feriez pour C / C ++, python, perl, ruby ou tout autre code de langage de programmation. La raison la plus profonde est labstraction – vous encapsulez les tâches de niveau inférieur dans des primitives (fonctions) de niveau supérieur afin que vous nayez pas à vous soucier de la façon dont les choses sont faites. En même temps, le code devient plus lisible (et maintenable), et le la logique du programme devient plus claire.
Cependant, en regardant votre code, je trouve assez étrange davoir une fonction pour déclarer des variables; cela me fait vraiment lever les yeux.
Commentaires
- Réponse sous-estimée IMHO. Proposez-vous de déclarer les variables dans la fonction / méthode
main
, alors?
Réponse
Une raison complètement différente de celles déjà données dans dautres réponses: une des raisons pour lesquelles cette technique est parfois utilisée, où la seule linstruction de non-définition de fonction au niveau supérieur est un appel à main
, est de sassurer que le script ne fait pas accidentellement quelque chose de mal si le script est tronqué. Le script peut être tronqué Si cest acheminé du processus A au processus B (le shell), et le processus A se termine pour une raison quelconque avant davoir fini décrire tout le script. Cela est particulièrement susceptible de se produire si le processus A récupère le script à partir dune ressource distante. Alors que pour des raisons de sécurité, ce nest pas une bonne idée, cest quelque chose qui est fait, et certains scripts ont été modifiés pour anticiper le problème.
Commentaires
- Intéressant! Mais je trouve troublant quil faille soccuper de ces choses dans chacun des programmes. Par contre, exactement ce motif
main()
est habituel en Python où lon utiliseif __name__ == '__main__': main()
à la fin du fichier. - Lidiome python a lavantage de laisser les autres scripts
import
le script actuel sans exécutermain
. Je suppose quune garde similaire pourrait être placée dans un script bash. - @Jake Cobb Oui. Je fais maintenant cela dans tous les nouveaux scripts bash. Jai un script qui contient une infrastructure de base de fonctions utilisées par tous les nouveaux scripts. Ce script peut être généré ou exécuté. Si source, sa fonction principale nest pas exécutée. La détection de la source vs exécution se fait via le fait que BASH_SOURCE contient le nom du script en cours dexécution. Si ‘ est identique au script principal, le script est en cours dexécution. Sinon, ‘ est en cours de sourçage.
- Étroitement lié à cette réponse, bash utilise un traitement basé sur des lignes simple lorsquil est exécuté à partir dun fichier déjà sur le disque. Si le fichier change pendant lexécution du script, le compteur de ligne ne ‘ t change et il ‘ continue sur la mauvaise ligne. Lencapsulation de tout dans les fonctions garantit que ‘ est entièrement chargé en mémoire avant dexécuter quoi que ce soit, donc la modification du fichier ne laffecte pas ‘.
Réponse
Quelques truismes pertinents sur la programmation:
- Votre programme va changer, même si votre patron insiste sur le fait que ce nest pas le cas.
- Seuls le code et lentrée affectent le comportement du programme.
- Nommer est difficile.
Les commentaires commencent comme un palliatif pour ne pas être capable dexprimer clairement vos idées dans le code *, et de saggraver (ou simplement de mal) avec le changement. Par conséquent, si possible, exprimez les concepts, les structures, le raisonnement, la sémantique, le flux, la gestion des erreurs et tout autre élément pertinent pour la compréhension du code sous forme de code.
Cela dit, Les fonctions Bash ont des problèmes introuvables dans la plupart des langages:
- Lespacement des noms est terrible dans Bash. Par exemple, si vous oubliez dutiliser le mot clé
local
, vous polluez lespace de noms global. - Lutilisation de
local foo="$(bar)"
entraîne perdre le code de sortie debar
. - Il ny a pas paramètres nommés, vous devez donc garder à l’esprit ce que
"$@"
signifie dans différents contextes.
* Je suis désolé si cela est offensant, mais après en utilisant des commentaires pendant quelques années et en développant sans eux ** pendant plus d années, il est assez clair ce qui est supérieur.
** Utiliser des commentaires pour les licences, la documentation API et autres est toujours nécessaire.
Commentaires
- Jai défini presque toutes les variables locales en les déclarant nulles au début de la fonction …
local foo=""
Puis les paramétrer à laide de lexécution de commande pour agir sur le résultat …foo="$(bar)" || { echo "bar() failed"; return 1; }
. Cela nous sort rapidement de la fonction lorsquune valeur requise ne peut pas être définie. Les accolades sont nécessaires pour garantir quereturn 1
ne soit exécuté quen cas déchec. - Je voulais juste commenter vos puces. Si vous utilisez des ‘ fonctions de sous-shell ‘ (fonctions délimitées par des parenthèses et non par des accolades), vous 1) don ‘ t avoir à utiliser local mais profiter des avantages de local, 2) Don ‘ t se heurter au problème de perdre le code de sortie de la substitution de commande dans
local foo=$(bar)
autant (car vous ‘ nutilisez pas local) 3) Ne ‘ que vous devez vous inquiéter concernant la pollution accidentelle ou la modification du périmètre mondial 4) sont capables de transmettre des ‘ paramètres nommés ‘ qui sont ‘ local ‘ à votre fonction en utilisant la syntaxefoo=bar baz=buz my-command
Réponse
Un processus nécessite une séquence. La plupart des tâches sont séquentielles. Cela na aucun sens de jouer avec la commande.
Mais lessentiel de la programmation – qui inclut les scripts – est le test. Test, test, test. De quels scripts de test disposez-vous actuellement pour valider lexactitude de vos scripts?
Votre patron essaie de vous guider, du statut de gamin de script à celui de programmeur. Cest une bonne direction à prendre. Les gens qui viennent après vous vous aimeront.
MAIS. Souvenez-vous toujours de vos racines orientées processus. Sil est judicieux de classer les fonctions dans lordre dans lequel elles sont généralement exécutées, alors faites-le, au moins comme une première passe.
Plus tard, vous verrez que certaines de vos fonctions sont gestion des entrées, dautres sorties, dautres traitements, dautres modélisant des données et dautres manipulant les données, il peut donc être judicieux de regrouper des méthodes similaires, peut-être même de les déplacer dans des fichiers séparés.
Plus tard encore, vous pourrez venez de réaliser que vous avez maintenant écrit des bibliothèques de petites fonctions daide que vous utilisez dans beaucoup de vos scripts.
Réponse
Commentaires et lespacement ne peut pas se rapprocher de la lisibilité que les fonctions peuvent, comme je vais le démontrer. Sans fonctions, vous ne pouvez pas voir la forêt des arbres – de gros problèmes se cachent entre de nombreuses lignes de détails. En dautres termes, les gens ne peuvent pas se concentrer simultanément sur les petits détails et sur la vue densemble. Cela peut ne pas être évident dans un script court; tant quil reste court, il peut être suffisamment lisible. Le logiciel sagrandit, mais pas plus petit , et certainement cela fait partie de tout le système logiciel de votre entreprise, qui est sûrement beaucoup plus grand, probablement des millions de lignes.
Considérez si je vous ai donné des instructions comme celle-ci:
Place your hands on your desk. Tense your arm muscles. Extend your knee and hip joints. Relax your arms. Move your arms backwards. Move your left leg backwards. Move your right leg backwards. (continue for 10,000 more lines)
Au moment où vous êtes à mi-chemin, voire 5%, vous auriez oublié quelles étaient les premières étapes. Vous ne pourriez pas repérer la plupart des problèmes, parce que vous ne pouviez pas voir la forêt pour les arbres. Comparez avec les fonctions:
stand_up(); walk_to(break_room); pour(coffee); walk_to(office);
Cest certainement beaucoup plus compréhensible, quel que soit le nombre de commentaires que vous pourriez mettre dans la version séquentielle ligne par ligne. rend également loin plus probable que vous « remarquerez que vous avez oublié de préparer le café, et probablement oublié sit_down () à la fin. Lorsque votre esprit pense aux détails des expressions rationnelles grep et awk, vous ne pouvez pas avoir une vue densemble – « Et sil ny a pas de café préparé »?
Les fonctions vous permettent principalement davoir une vue densemble, et remarquez que vous avez oublié de préparer le café (ou que quelquun pourrait préférer le thé). À un autre moment, dans un autre état desprit, vous vous inquiétez de la mise en œuvre détaillée.
Il y a aussi dautres avantages abordés dans Un autre avantage qui nest pas clairement indiqué dans les autres réponses est que les fonctions fournissent une garantie importante pour prévenir et corriger les bogues. Si vous découvrez quune variable $ foo dans la fonction appropriée walk_to () était fausse, vous savez que vous navez quà regarder les 6 autres lignes de cette fonction pour trouver tout ce qui aurait pu être affecté par ce problème, et tout ce qui pourrait ont causé une erreur. Sans les fonctions (appropriées), tout et nimporte quoi dans lensemble du système pourrait être une cause de $ foo incorrect, et tout et tout pourrait être affecté par $ foo. Par conséquent, vous ne pouvez pas corriger en toute sécurité $ foo sans réexaminer chaque ligne du programme. Si $ foo est local à une fonction, vous pouvez garantir que toutes les modifications sont sûres et correctes en ne vérifiant que cette fonction.
Commentaires
- Cette syntaxe nest pas ‘ t
bash
.Cest ‘ que cest dommage cependant; Je ne ‘ ne pense pas quil existe un moyen de passer des entrées à des fonctions comme ça. (cest-à-direpour();
<coffee
). Cela ressemble plus àc++
ouphp
(je pense). - @ tjt263 sans les parenthèses, il ‘ s syntaxe bash: pour le café. Avec les parens, cest ‘ quasiment toutes les autres langues. 🙂
Réponse
Le temps, cest de largent
Il existe dautres bonnes réponses qui éclairent les raisons techniques décrire de manière modulaire un script, potentiellement long, développé dans un environnement de travail, développé pour être utilisé par un groupe de personnes et pas seulement pour votre propre usage.
Je veux se concentrer sur une attente: dans un environnement de travail « time is money » . Ainsi, labsence de bugs et les performances de votre code sont évaluées avec lisibilité , testabilité, maintenabilité, refactorabilité, réutilisabilité …
Écriture en » modules « un code diminuera le temps de lecture nécessaire non seulement par le codeur lui-même, mais même le temps utilisé par les testeurs ou par le patron. De plus notez que le temps dun boss est généralement payé plus que le temps dun codeur et que votre patron évaluera la qualité de votre travail.
De plus, écrire en indépendant « modules » un code (même un script bash) vous permettra de travailler en « parallèle » avec autre composant de votre équipe raccourcissant le temps de production global et utilisant au mieux lexpertise du single, pour revoir ou réécrire une pièce sans effet secondaire sur les autres, pour recycler le code que vous venez décrire « tel quel » pour un autre programme / script, pour créer des bibliothèques (ou des bibliothèques dextraits de code), pour réduire la taille globale et la probabilité derreurs associée, pour déboguer et tester en profondeur chaque partie … et bien sûr, il organisera en logique sectionnez votre programme / script et améliorez sa lisibilité. Tout cela vous fera gagner du temps et donc de largent. Linconvénient est que vous devez vous en tenir aux standards et commenter vos fonctions (que vous pas à faire dans un environnement de travail).
Adhérer à une norme ralentira votre travail au début mais cela accélérera le travail de tous les autres (et le vôtre aussi) par la suite. En effet, lorsque la collaboration augmente en nombre de personnes impliquées, cela devient un besoin incontournable. Ainsi, par exemple, même si je pense que les variables globales doivent être définies globalement et non dans une fonction, je peux comprendre un standard qui les initialise dans une fonction nommée declare_variables()
toujours appelé dans la première ligne de main()
…
Dernier point mais non le moindre, ne sous-estimez pas la possibilité dans le code source moderne éditeurs pour afficher ou masquer des routines sélectivement séparées ( Pliage de code ). Cela gardera le code compact et focalisé sur lutilisateur en économisant à nouveau du temps.
Ci-dessus, vous pouvez voir comment il est déplié uniquement la fonction walk_into_bar()
. Même les autres faisaient 1000 lignes chacun, vous pouviez toujours garder sous contrôle tout le code dans une seule page. Notez quil est plié même la section où vous allez déclarer / initialiser les variables.
Réponse
Autre raison qui est souvent négligée est lanalyse syntaxique de bash:
set -eu echo "this shouldn"t run" { echo "this shouldn"t run either"
Ce script contient évidemment une erreur de syntaxe et bash ne devrait pas du tout lexécuter, non? Faux.
~ $ bash t1.sh this shouldn"t run t1.sh: line 7: syntax error: unexpected end of file
Si nous enveloppions le code dans une fonction, cela ne se produirait pas:
set -eu main() { echo "this shouldn"t run" { echo "this shouldn"t run either" } main
~ $ bash t1.sh t1.sh: line 10: syntax error: unexpected end of file
Réponse
Outre les raisons données dans dautres réponses:
- Psychologie: un programmeur dont la productivité est mesurée en lignes de code sera incité à écrire du code inutilement verbeux. Plus la gestion est en se concentrant sur les lignes de code, plus le programmeur est incité à étendre son code avec une complexité inutile, ce qui nest pas souhaitable car une complexité accrue peut entraîner une augmentation des coûts de maintenance et des efforts accrus pour la correction des bogues.
Commentaires
- Ce nest pas une si mauvaise réponse, comme le disent les votes négatifs. Remarque: agc dit, cest aussi une possibilité, et oui, cest le cas. Il ne ‘ t dit que ce serait la seule possibilité, et ne ‘ t accuse personne, ne précise que les faits. Même si je pense qu’aujourd’hui, il est presque impossible d’entendre une » ligne de code » – > » $$ » style contrat de travail, sur indirect signifie quil est assez courant, que oui, la masse du code produit compte par les leaders / bosses.
main()
en haut et jajoutemain "$@"
en bas pour lappeler. Cela vous permet de voir le haut la logique du script de niveau en premier lorsque vous louvrez.local
– ceci fournit la variable scope qui est extrêmement importante dans tout script non trivial.