Waarom een volledig bash-script schrijven in functies?

Op het werk schrijf ik regelmatig bash-scripts. Mijn supervisor heeft gesuggereerd dat het volledige script wordt opgedeeld in functies, vergelijkbaar met het volgende voorbeeld:

#!/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 

Is er een andere reden om dit te doen dan “leesbaarheid” , waarvan ik denk dat het even goed ingeburgerd zou kunnen zijn met nog een paar opmerkingen en wat regelafstand?

Zorgt het ervoor dat het script efficiënter werkt (ik zou eigenlijk het tegenovergestelde verwachten, als er iets is), of het gemakkelijker is om de code te wijzigen buiten het eerder genoemde leesbaarheidspotentieel? Of is het eigenlijk gewoon een stilistische voorkeur?

Houd er rekening mee dat, hoewel het script het niet goed aantoont, de volgorde van de functies in onze huidige scripts erg lineair is – walk_into_bar hangt af van dingen die i_am_foo heeft gedaan, en do_baz werkt op dingen die zijn ingesteld door walk_into_bar – dus het willekeurig kunnen omwisselen van de startvolgorde is niet iets dat we normaal gesproken zouden doen. Je zou bijvoorbeeld niet ineens declare_variables na walk_into_bar willen plaatsen, dat zou dingen kapot maken.

Een voorbeeld van hoe ik het bovenstaande script zou schrijven zou zijn:

#!/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 

Reacties

  • Ik vind je leuk baas. In mijn scripts heb ik ook main() bovenaan gezet en main "$@" onderaan om het te noemen. Zo kun je de hoogte zien niveau scriptlogica als eerste wanneer je het opent.
  • Ik ben het niet eens met het idee dat de leesbaarheid ” even goed ingeburgerd kan zijn met nog een paar opmerkingen en wat regelafstand . ” Behalve misschien voor fictie, zou ik ‘ niet willen omgaan met een boek dat niet ‘ t hebben een inhoudsopgave en beschrijvende namen voor elk hoofdstuk en elke sectie. In programmeertalen is dat ‘ het soort leesbaarheid dat functies kunnen bieden, een nd comment ‘ s kan ‘ t.
  • Merk op dat variabelen gedeclareerd in functies moeten worden gedeclareerd local – dit levert een variabele scope op, wat ongelooflijk belangrijk is in elk niet-triviaal script.
  • Ik ben het niet eens met je baas. Als je je script in functies moet opsplitsen, moet je waarschijnlijk ‘ überhaupt geen shellscript schrijven. Schrijf in plaats daarvan een programma.
  • Functies zijn voor processen die worden herhaald, hetzij binnen het script of in meer dan één script. Ze maken het ook mogelijk om uniforme methodologieën in te voeren. Bijv. Een functie gebruiken om naar syslog te schrijven. Zolang iedereen dezelfde functie gebruikt, zijn uw syslog-items consistenter. Functies voor eenmalig gebruik zoals uw voorbeeld maken het script onnodig ingewikkeld. In sommige gevallen introduceren ze problemen (variabele scoping).

Antwoord

Ik ben deze zelfde gaan gebruiken stijl van bash-programmeren na het lezen van Kfir Lavis blogpost “Defensive Bash Programming” . Hij geeft nogal wat goede redenen, maar persoonlijk vind ik deze de belangrijkste:

  • procedures worden beschrijvend: het is veel gemakkelijker om erachter te komen wat een bepaald deel van de code wordt verondersteld te doen. In plaats van een muur met code, zie je “Oh, de find_log_errors -functie leest dat logbestand voor fouten”. Vergelijk het met het vinden van heel veel awk / grep / sed-regels die gebruik god weet wat voor soort regex in het midden van een lang script – je “hebt geen idee wat” het daar doet, tenzij er commentaar is.

  • je kunt functies debuggen door set -x en set +x. Als je eenmaal weet dat de rest van de code goed werkt, kun je deze truc gebruiken om je te concentreren op het debuggen van alleen die specifieke functie. Natuurlijk kun je delen van het script insluiten, maar wat als het “een lang gedeelte is? Het is gemakkelijker om zoiets als dit te doen:

     set -x parse_process_list set +x 
  • afdrukgebruik met cat <<- EOF . . . EOF. Ik heb het al een paar keer gebruikt om mijn code veel professioneler te maken. Bovendien is parse_args() met getopts functie best handig. Nogmaals, dit helpt bij de leesbaarheid, in plaats van alles in het script te stoppen als een gigantische muur met tekst. Het is ook handig om deze opnieuw te gebruiken.

En uiteraard is dit veel meer leesbaar voor iemand die C of Java of Vala kent, maar beperkte bash-ervaring heeft. Wat efficiëntie betreft, er is niet veel van wat je kunt doen – bash zelf is niet de meest efficiënte taal en mensen geven de voorkeur aan perl en python als het gaat om snelheid en efficiëntie.U kunt echter nice een functie:

nice -10 resource_hungry_function 

In vergelijking met het aanroepen van nice op elke regel code, dit vermindert heel veel typen EN kan handig worden gebruikt als u wilt dat slechts een deel van uw script met lagere prioriteit wordt uitgevoerd.

Het uitvoeren van functies op de achtergrond helpt naar mijn mening ook als u hele een heleboel uitspraken om op de achtergrond uit te voeren.

Enkele voorbeelden waarin ik “deze stijl heb gebruikt:

Opmerkingen

  • Ik weet niet zeker of je suggesties uit dat artikel serieus moet nemen. Toegegeven, het heeft een paar goede ideeën, maar het is duidelijk niet iemand die gewend is aan shell-scripting. Geen enkele variabele in elk van de voorbeelden wordt geciteerd (!) en het stelt voor om UPPER C te gebruiken ASE-variabelenamen, wat vaak een heel slecht idee is, omdat ze in strijd kunnen zijn met bestaande env vars. Uw punten in dit antwoord zijn logisch, maar het gelinkte artikel lijkt te zijn geschreven door iemand die net gewend is aan andere talen en die probeert zijn stijl op bash te forceren.
  • @terdon Ik ging terug naar het artikel en las het opnieuw. De enige plaats waar de auteur variabelen in hoofdletters noemt, is in ” Onveranderlijke globale variabelen “. Als u globale variabelen beschouwt als variabelen die binnen de omgeving van functie ‘ moeten vallen, dan is het logisch om ze met een hoofdletter te maken. Even terzijde, bash ‘ s handleiding heeft geen ‘ statusconventie voor variabel hoofdlettergebruik. Zelfs hier geaccepteerd antwoord zegt ” meestal ” en het enige ” standard ” is van Google, dat niet ‘ de hele IT-industrie vertegenwoordigt.
  • @terdon op een andere opmerking, ik ben het er 100% mee eens dat het citeren van variabelen in het artikel had moeten worden vermeld, en er is ook op gewezen in de commentaren op de blog. Ook zou ik ‘ niet beoordelen of iemand deze stijl van coderen gebruikt, ongeacht of ze ‘ in een andere taal zijn gebruikt. Deze hele vraag en antwoorden laten duidelijk de ‘ s voordelen zien, en de ‘ mate waarin ze ‘ opnieuw gebruikt in een andere taal is hier waarschijnlijk niet relevant.
  • @terdon nou, het artikel is gepost als onderdeel van de ” bron ” materiaal. Ik had alles als mijn eigen mening kunnen posten, maar ik moest gewoon de eer geven dat sommige dingen die ik uit het artikel leerde, en dat dit allemaal voortkwam uit onderzoek in de loop van de tijd. De LinkedIn-pagina van de auteur ‘ laat zien dat ze goede ervaring hebben met Linux en IT in het algemeen, dus ik ‘ denk dat het artikel niet ‘ laat dat niet echt zien, maar ik vertrouw op je ervaring als het gaat om Linux en shellscripting, dus misschien heb je gelijk.
  • Dat ‘ is een uitstekend antwoord, maar ik ‘ zou ook graag willen toevoegen dat de variabele scope in Bash funky is. Om die reden geef ik er de voorkeur aan om mijn variabelen binnen functies te declareren met local en alles aan te roepen via de main() functie. Dit maakt de zaken een stuk beter beheersbaar en u kunt een mogelijk rommelige situatie vermijden.

Antwoord

Leesbaarheid is één ding. Maar modularisatie is meer dan alleen dit. ( Semi-modularisatie is misschien juister voor functies.)

In functies kun je enkele variabelen lokaal houden, wat de betrouwbaarheid verhoogt, waardoor de kans op dingen worden in de war.

Een ander voordeel van functies is herbruikbaarheid . Als een functie eenmaal is gecodeerd, kan deze meerdere keren in het script worden toegepast. U kunt het ook naar een ander script overzetten.

Uw code is nu misschien lineair, maar in de toekomst kunt u het rijk van multi-threading of multi- verwerking in de Bash-wereld. Als je eenmaal leert om dingen in functies te doen, ben je goed uitgerust voor de stap naar de parallel.

Nog een punt om toe te voegen. Zoals Etsitpab Nioliv opmerkt in de opmerking hieronder, is het gemakkelijk om vanuit functies om te leiden als een samenhangende entiteit. Maar er is nog een aspect van omleidingen met functies. De omleidingen kunnen namelijk worden ingesteld volgens de functiedefinitie. Bijv .:

f () { echo something; } > log 

Nu zijn er geen expliciete omleidingen nodig voor de functieaanroepen.

$ f 

Dit kan veel herhalingen sparen, wat opnieuw de betrouwbaarheid verhoogt en helpt om de zaken op orde te houden.

Zie ook

Reacties

  • Zeer goed antwoord, hoewel het veel beter zou zijn als het in functies was opgesplitst.
  • Voeg misschien die functies toe om dat script in een ander script te importeren (door source of . scriptname.sh, en gebruik die functies alsof ze in je nieuwe script staan.
  • Dat ‘ is al gedekt in een ander antwoord.
  • Dat waardeer ik. Maar ik ‘ liet andere mensen liever ook belangrijk zijn.
  • Ik stond voor een zaak vandaag, waar ik een deel van de uitvoer van een script naar een bestand moest omleiden (om het via e-mail te verzenden) in plaats van te echoën. Ik moest gewoon myFunction > myFile om de uitvoer van de gewenste functies om te leiden. Best handig. Kan relevant zijn.

Answer

In mijn opmerking noemde ik drie voordelen van functies:

  1. Ze zijn gemakkelijker te testen en correctheid te verifiëren.

  2. Functies kunnen gemakkelijk worden hergebruikt (sourcen) in toekomstige scripts

  3. Je baas vindt ze leuk.

En onderschat nooit het belang van nummer 3.

Ik wil nog een probleem aanpakken:

… dus in staat zijn om willekeurig de run-volgorde om te wisselen is niet iets wat we normaal gesproken zouden doen. Je zou bijvoorbeeld niet ineens declare_variables na walk_into_bar willen plaatsen, dat zou dingen kapot maken.

Om het voordeel te krijgen dat code in functies wordt opgesplitst, moet men proberen de functies zo onafhankelijk mogelijk te maken. Als walk_into_bar een variabele vereist die wordt nergens anders gebruikt, dan moet die variabele worden gedefinieerd in en lokaal worden gemaakt in walk_into_bar. Het proces van het scheiden van de code in functies en het minimaliseren van hun onderlinge afhankelijkheden zou de code duidelijker en eenvoudiger moeten maken .

Idealiter zouden functies eenvoudig afzonderlijk te testen moeten zijn. Als ze vanwege interacties niet gemakkelijk te testen zijn, dan is dat een teken dat ze baat kunnen hebben bij refactoring.

Opmerkingen

  • Ik ‘ d beweer dat het ‘ soms verstandig is om te modelleren en die afhankelijkheden afdwingen, in plaats van refactoring om ze te vermijden (want als er genoeg zijn h van hen, en ze ‘ zijn voldoende behaard, dat kan gewoon leiden tot een geval waarin dingen helemaal niet meer in functies worden gemodulariseerd). Een zeer gecompliceerde use-case inspireerde ooit een framework om precies dat te doen .
  • Wat moet worden onderverdeeld in functies zou dat moeten zijn, maar het voorbeeld gaat te ver. Ik denk dat de enige die me echt irriteert, de variabele declaratiefunctie is. Globale variabelen, vooral statische variabelen, moeten globaal worden gedefinieerd in een speciaal voor dat doel becommentarieerd gedeelte. Dynamische variabelen moeten lokaal zijn voor de functies die ze gebruiken en wijzigen.
  • @Xalorous I ‘ heb een praktijk gezien waarbij globale variabelen worden geïnitialiseerd in een procedure, als een tussenliggende en snelle stap voor de ontwikkeling van een procedure die hun waarde uit een extern bestand leest … Ik ben het ermee eens dat het schoner zou moeten zijn om de definitie en initialisatie te scheiden, maar je hoeft zelden te buigen om de voordeel nummer 3 ;-)

Antwoord

Hoewel ik het helemaal eens ben met de herbruikbaarheid , leesbaarheid , en het subtiel kussen van de bazen, maar er is nog een ander voordeel van functies in : variabel bereik . Zoals LDP laat zien :

#!/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. 

Ik zie dit niet zo vaak in de echte wereld shell-scripts, maar het lijkt een goed idee voor complexere scripts. Door cohesie te verminderen, worden bugs voorkomen waarbij u een variabele in de war brengt die wordt verwacht in een ander deel van de code .

Herbruikbaarheid betekent vaak het creëren van een gemeenschappelijke bibliotheek met functies en source die bibliotheek in al uw scripts opnemen. Dit zal ze niet helpen sneller te werken, maar het zal je wel helpen om ze sneller te schrijven.

Reacties

  • Er zijn maar weinig mensen die local, maar ik denk dat de meeste mensen die scripts schrijven opgedeeld in functies nog steeds het ontwerpprincipe volgen. Usign local maakt het alleen moeilijker om bugs te introduceren.
  • local stelt variabelen beschikbaar om te functioneren en de onderliggende variabelen, dus het ‘ is erg leuk om een variabele te hebben die kan worden doorgegeven lager dan functie A, maar niet beschikbaar voor functie B, die misschien een variabele wil hebben met dezelfde naam maar een ander doel.Zodat ‘ goed is voor het definiëren van de scope, en zoals Voo zei – minder bugs

Answer

Je splitst de code op in functies om dezelfde reden dat je dat zou doen voor C / C ++, python, perl, ruby of welke programmeertaal dan ook. De diepere reden is abstractie – u kapselt taken op een lager niveau in in primitieven (functies) van een hoger niveau, zodat u zich geen zorgen hoeft te maken over hoe dingen worden gedaan. Tegelijkertijd wordt de code beter leesbaar (en onderhoudbaar), en de Programmalogica wordt duidelijker.

Als ik echter naar je code kijk, vind ik het nogal vreemd om een functie te hebben om variabelen te declareren; dit doet me echt een wenkbrauw optrekken.

Opmerkingen

  • Onderschat antwoord IMHO. Stel je dan voor om de variabelen in de main functie / methode te declareren?

Antwoord

Een geheel andere reden dan die al in andere antwoorden zijn gegeven: een reden waarom deze techniek soms wordt gebruikt, waarbij de enige non-function-definition statement op het hoogste niveau is een aanroep van main, om ervoor te zorgen dat het script niet per ongeluk iets vervelends doet als het script wordt afgekapt. Het script kan worden afgekapt als het is doorgesluisd van proces A naar proces B (de shell), en proces A wordt om welke reden dan ook beëindigd voordat het klaar is met het schrijven van het hele script. Dit is vooral waarschijnlijk als proces A het script ophaalt van een externe bron. Hoewel dat om veiligheidsredenen geen goed idee is, is het iets dat wordt gedaan en sommige scripts zijn aangepast om op het probleem te anticiperen.

Opmerkingen

  • Interessant! Maar ik vind het verontrustend dat je voor die dingen moet zorgen in elk van de programmas. Aan de andere kant is precies dit main() patroon gebruikelijk in Python, waar men if __name__ == '__main__': main() aan het einde van het bestand gebruikt.
  • Het python-idioom heeft het voordeel dat andere scripts import het huidige script laten draaien zonder main uit te voeren. Ik veronderstel dat een soortgelijke bewaker in een bash-script kan worden geplaatst.
  • @Jake Cobb Ja. Ik doe dat nu in alle nieuwe bash-scripts. Ik heb een script dat een kerninfrastructuur van functies bevat die door alle nieuwe scripts worden gebruikt. Dat script kan worden verkregen of uitgevoerd. Indien afkomstig, wordt de hoofdfunctie niet uitgevoerd. Detectie van bron versus uitvoering is via het feit dat de BASH_SOURCE de naam van het uitvoerende script bevat. Als het ‘ hetzelfde is als het kernscript, wordt het script uitgevoerd. Anders wordt het ‘ gebruikt als bron.
  • Nauw verwant aan dit antwoord, gebruikt bash eenvoudige, op regels gebaseerde verwerking wanneer het draait vanuit een bestand dat al op schijf staat. Als het bestand verandert terwijl het script wordt uitgevoerd, verandert de lijnteller niet ‘ t en gaat het ‘ verder op de verkeerde regel. Alles inkapselen in functies zorgt ervoor dat het ‘ allemaal in het geheugen wordt geladen voordat iets wordt uitgevoerd, dus het wijzigen van het bestand heeft geen ‘ invloed op het.

Antwoord

Enkele relevante feiten over programmeren:

  • Je programma zal veranderen, zelfs als je baas volhoudt dat dit niet het geval is.
  • Alleen code en invoer beïnvloeden het gedrag van het programma.
  • benoemen is moeilijk.

Reacties beginnen als een noodoplossing voor het niet zijn in staat om uw ideeën duidelijk in code * uit te drukken, en erger (of gewoon fout) te worden met veranderingen. Geef daarom, indien mogelijk, concepten, structuren, redeneringen, semantiek, flow, foutafhandeling en al het andere dat relevant is voor het begrijpen van de code als code.

Dat gezegd hebbende, Bash-functies hebben een aantal problemen die niet in de meeste talen voorkomen:

  • Naamruimte is verschrikkelijk in Bash. Als u bijvoorbeeld het trefwoord local vergeet te gebruiken, vervuilt de globale naamruimte.
  • Het gebruik van local foo="$(bar)" resulteert in verliest de afsluitcode van bar .
  • Er zijn geen benoemde parameters, dus u moet in gedachten houden wat "$@" betekent in verschillende contexten.

* Het spijt me als dit beledigt, maar na het gebruik van commentaar voor een aantal jaren en het ontwikkelen zonder hen ** voor meer jaren is het vrij duidelijk wat superieur is.

** Het gebruik van commentaar voor licenties, API-documentatie en dergelijke is nog steeds nodig.

Opmerkingen

  • Ik heb bijna alle lokale variabelen ingesteld door ze aan het begin van de functie op null te verklaren …local foo="" Stel ze vervolgens in met behulp van opdrachtuitvoering om te reageren op het resultaat … foo="$(bar)" || { echo "bar() failed"; return 1; }. Dit haalt ons snel uit de functie wanneer een vereiste waarde niet kan worden ingesteld. De accolades zijn nodig om er zeker van te zijn dat de return 1 alleen wordt uitgevoerd bij een mislukking.
  • Ik wilde alleen maar een opmerking maken over je opsommingstekens. Als u ‘ subshell-functies ‘ gebruikt (functies gescheiden door haakjes en geen accolades), 1) don ‘ je hoeft niet lokaal te gebruiken, maar profiteer van de voordelen van lokaal, 2) Loop niet ‘ tegen het probleem aan van het verliezen van de exitcode van opdrachtvervanging in local foo=$(bar) evenveel (omdat je ‘ geen gebruik maakt van lokaal) 3) Maak ‘ geen zorgen over het per ongeluk vervuilen of wijzigen van het globale bereik 4) kunnen ‘ genoemde parameters ‘ passeren die ‘ local ‘ naar uw functie door de syntaxis foo=bar baz=buz my-command

Antwoord

Een proces vereist een reeks. De meeste taken zijn opeenvolgend. Het heeft geen zin om met de bestelling te rotzooien.

Maar het super grote ding over programmeren – inclusief scripting – is testen. Testen, testen, testen. Welke testscripts heb je momenteel om de juistheid van je scripts te valideren?

Je baas probeert je te begeleiden van een scriptkiddy naar een programmeur. Dit is een goede richting om in te gaan. Mensen die na je komen zullen je aardig vinden.

MAAR. Onthoud altijd uw procesgeoriënteerde wortels. Als het zinvol is om de functies te ordenen in de volgorde waarin ze doorgaans worden uitgevoerd, doe dat dan in ieder geval als eerste doorgang.

Later zul je zien dat sommige van je functies omgaan met input, anderen met output, anderen die verwerken, anderen modelleren van data, en anderen die de data manipuleren, dus het kan slim zijn om soortgelijke methodes te groeperen, misschien zelfs om ze in aparte bestanden te plaatsen.

Nog later realiseer je dat je “nu bibliotheken hebt geschreven met kleine hulpfuncties die je in veel van je scripts gebruikt.

Antwoord

Opmerkingen en de afstand kan niet in de buurt komen van de leesbaarheid die functies wel kunnen, zoals ik zal aantonen. Zonder functies zie je door de bomen het bos niet – grote problemen verbergen zich tussen vele detailregels. Met andere woorden, mensen kunnen “niet tegelijkertijd focussen op de fijne details en op het grote geheel. Dat is misschien niet duidelijk in een kort script; zolang het kort blijft, kan het leesbaar genoeg zijn. Software wordt echter groter, niet kleiner. , en het maakt zeker deel uit van het volledige softwaresysteem van uw bedrijf, dat zeker veel groter is, waarschijnlijk miljoenen regels.

Overweeg of ik u instructies zoals deze zou geven:

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) 

Tegen de tijd dat je halverwege was, of zelfs 5%, zou je vergeten zijn wat de eerste paar stappen waren. Je kon de meeste problemen niet zien, omdat je door de bomen het bos niet meer kon zien. Vergelijk met functies:

stand_up(); walk_to(break_room); pour(coffee); walk_to(office); 

Dat is zeker veel begrijpelijker, ongeacht hoeveel commentaren u in de regel voor regel opeenvolgende versie zou kunnen plaatsen. maakt het ook ver waarschijnlijker dat je bent vergeten de koffie te zetten, en waarschijnlijk sit_down () aan het einde vergeten. Als je geest aan de details van grep en awk regexes denkt, kun je “niet denken aan het grote geheel -” wat als er geen koffie wordt gezet “?

Functies stellen je voornamelijk in staat het grote geheel te zien, en merkt dat u bent vergeten koffie te zetten (of dat iemand de voorkeur geeft aan thee). Op een ander moment, met een andere gemoedstoestand, maakt u zich zorgen over de gedetailleerde implementatie.

Er worden ook andere voordelen besproken in andere antwoorden natuurlijk Een ander voordeel dat niet duidelijk wordt vermeld in de andere antwoorden is dat functies een garantie bieden die belangrijk is bij het voorkomen en verhelpen van bugs. Als je ontdekt dat een variabele $ foo in de juiste functie walk_to () verkeerd was, weet je dat je alleen naar de andere 6 regels van die functie hoeft te kijken om alles te vinden dat door dat probleem zou kunnen zijn beïnvloed, en alles wat zou kunnen hebben ervoor gezorgd dat het verkeerd is. Zonder (juiste) functies kan alles en nog wat in het hele systeem de oorzaak zijn dat $ foo incorrect is, en alles en nog wat kan worden beïnvloed door $ foo. Daarom kun je $ foo niet veilig repareren zonder elke regel van het programma opnieuw te onderzoeken. Als $ foo lokaal is voor een functie, kun je garanderen dat alle wijzigingen veilig en correct zijn door alleen die functie te controleren.

Opmerkingen

  • Dit is niet ‘ t bash syntaxis.Het is echter ‘ jammer; Ik denk niet dat ‘ niet dat er een manier is om invoer door te geven aan dergelijke functies. (bijv. pour(); < coffee). Het lijkt meer op c++ of php (denk ik).
  • @ tjt263 zonder de haakjes, het is ‘ s bash-syntaxis: giet koffie. Met parens is het ‘ vrijwel elke andere taal. 🙂

Antwoord

Tijd is geld

Er zijn andere goede antwoorden die licht werpen op de technische redenen om modulair een script te schrijven, mogelijk lang, ontwikkeld in een werkomgeving, ontwikkeld om te worden gebruikt door een groep personen en niet alleen voor eigen gebruik.

Ik wil focus op één verwachting: in een werkomgeving “tijd is geld” . Dus de afwezigheid van bugs en de prestaties van uw code worden geëvalueerd samen met leesbaarheid , testbaarheid, onderhoudbaarheid, refactorability, herbruikbaarheid

Schrijven in ” modules “ een code vermindert de leestijd die niet alleen nodig is door de coder zelf, maar zelfs de tijd die wordt gebruikt door de testers of door de baas. Merk bovendien op dat de tijd van een baas meestal meer wordt betaald dan de tijd van een coder en dat je baas de kwaliteit van je baan zal beoordelen.

Verder schrijven in onafhankelijke “modules” een code (zelfs een bash-script) stelt u in staat om “parallel” te werken met andere component van uw team die de algehele productietijd verkort en op zijn best de expertise van de single gebruikt, om een deel te herzien of te herschrijven zonder bijeffecten op de anderen, om de code die u zojuist hebt geschreven te recyclen “as is” voor een ander programma / script, om bibliotheken (of bibliotheken met fragmenten) te maken, om de algehele grootte en de gerelateerde waarschijnlijkheid van fouten te verkleinen, om elk afzonderlijk onderdeel grondig te debuggen en te testen … en natuurlijk zal het logisch worden georganiseerd deel uw programma / script en verbeter de leesbaarheid. Alle dingen die tijd en dus geld besparen. Het nadeel is dat u zich aan standaarden moet houden en commentaar moet geven op uw functies (die u niet te doen in een werkomgeving).

Als u zich aan een standaard houdt, wordt uw werk vertraagd in het begin maar het zal het werk van alle anderen (en ook die van jou) daarna versnellen. Inderdaad, wanneer de samenwerking groeit in het aantal betrokken personen, wordt dit een onvermijdelijke behoefte. Dus zelfs als ik denk dat de globale variabelen globaal moeten worden gedefinieerd en niet in een functie, kan ik een standaard begrijpen die ze inizialiseert in een functie met de naam declare_variables() altijd genoemd in de eerste regel van de main() een …

Last but not least, onderschat de mogelijkheid in moderne broncode niet editors om selectief afzonderlijke routines te tonen of te verbergen ( Code invouwen ). Hierdoor blijft de code compact en bespaart de gebruiker opnieuw tijd.

voer de beschrijving van de afbeelding hier in

Hierboven kun je zien hoe het is uitgevouwen alleen de walk_into_bar() functie. Zelfs van de andere waren elk 1000 regels lang, je kon nog steeds alle code op één pagina onder controle houden. Merk op dat het zelfs het gedeelte is waar je naartoe gaat om de variabelen te declareren / initialiseren.

Antwoord

Een andere reden dat vaak over het hoofd wordt gezien, is het parseren van de syntaxis van bash:

set -eu echo "this shouldn"t run" { echo "this shouldn"t run either" 

Dit script bevat duidelijk een syntaxisfout en bash zou het helemaal niet moeten uitvoeren, toch? Fout.

~ $ bash t1.sh this shouldn"t run t1.sh: line 7: syntax error: unexpected end of file 

Als we de code in een functie zouden stoppen, zou dit niet gebeuren:

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 

Antwoord

Afgezien van de redenen die in andere antwoorden worden gegeven:

  1. Psychologie: een programmeur wiens productiviteit wordt gemeten in regels code, wordt gestimuleerd om onnodig uitgebreide code te schrijven. Als u zich concentreert op coderegels, des te meer prikkel de programmeur heeft om zijn code met onnodige complexiteit uit te breiden. Dit is ongewenst aangezien een grotere complexiteit kan leiden tot hogere onderhoudskosten en meer inspanning die nodig is voor het oplossen van fouten.

Reacties

  • Het is niet zon slecht antwoord, zoals de downvotes zeggen. Let op: agc zegt, ook dit is een mogelijkheid, en ja, het is. Hij ‘ zegt niet dat dit de enige mogelijkheid zou zijn, en ‘ beschuldigt niemand, maar vermeldt alleen de feiten. Hoewel ik denk dat het vandaag bijna ongehoord is, is een directe ” coderegel ” – > ” $$ ” stijl contracttaak, op indirecte wijze is het vrij gebruikelijk dat ja, de massa van de geproduceerde code telt door de leiders / bazen.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *