På jobbet skriver jag ofta bash-skript. Min handledare har föreslagit att hela skriptet ska delas in i funktioner, liknande följande exempel:
#!/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
Finns det någon anledning att göra detta annat än ”läsbarhet” , vilket jag tror kan vara lika väl etablerat med några fler kommentarer och lite radavstånd?
Gör det att skriptet går mer effektivt (jag förväntar mig faktiskt det motsatta, om något), eller gör det är det lättare att ändra koden utöver den tidigare nämnda läsbarhetspotentialen? Eller är det egentligen bara en stilistisk preferens?
Observera att även om skriptet inte visar det bra, så ”kör ordningen” på funktionerna i våra faktiska skript tenderar att vara väldigt linjär – walk_into_bar
beror på saker som i_am_foo
har gjort, och do_baz
agerar på saker som ställts in av walk_into_bar
– så att vi godtyckligt kan byta körordning är inte något vi vanligtvis skulle göra. Till exempel vill du inte plötsligt lägga declare_variables
efter walk_into_bar
, det skulle bryta saker.
En exempel på hur jag skulle skriva ovanstående skript skulle vara:
#!/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
Kommentarer
Svar
Jag har börjat använda samma stil för bash-programmering efter att ha läst Kfir Lavis blogginlägg ”Defensive Bash Programming” . Han ger en hel del bra skäl, men personligen tycker jag att dessa är de viktigaste:
-
procedurerna blir beskrivande: det är mycket lättare att räkna ut vad en viss del av koden är tänkt att göra. I stället för kodvägg ser du ”Åh,
find_log_errors
-funktionen läser den loggfilen för fel”. Jämför den med att hitta en hel del awk / grep / sed-linjer som använd gud vet vilken typ av regex mitt i ett långt skript – du har ingen aning om vad det gör där om det inte finns kommentarer. -
du kan felsöka funktioner genom att bifoga i
set -x
ochset +x
. När du väl vet att resten av koden fungerar, kan du använda detta trick för att fokusera på att felsöka bara den specifika funktionen. Visst, du kan bifoga delar av skriptet, men tänk om det är en lång del? Det är lättare att göra något så här:set -x parse_process_list set +x
-
utskriftsanvändning med
cat <<- EOF . . . EOF
. Jag har använt det ganska många gånger för att göra min kod mycket mer professionell. Dessutom ärparse_args()
medgetopts
-funktionen ganska bekväm. Återigen, detta hjälper till med läsbarheten, istället för att skjuta allt till skript som en jätte textvägg. Det är också bekvämt att återanvända dessa.
Och det är uppenbarligen mycket mer läsbar för någon som kan C eller Java, eller Vala, men har begränsad bash-upplevelse. När det gäller effektivitet går det inte mycket av vad du kan göra – själva bash är inte det mest effektiva språket och folk föredrar perl och python när det gäller hastighet och effektivitet.Du kan dock nice
en funktion:
nice -10 resource_hungry_function
Jämfört med att ringa trevligt på varje rad kod, detta minskar en hel del skrivning OCH kan bekvämt användas när du bara vill att en del av ditt skript ska köras med lägre prioritet.
Att köra funktioner i bakgrunden hjälper enligt min mening också när du vill ha hela massa uttalanden som ska köras i bakgrunden.
Några av exemplen där jag har använt den här stilen:
- https://askubuntu.com/a/758339/295286
- https://askubuntu.com/a/788654/295286
- https://github.com/SergKolo/sergrep/blob/master/chgreeterbg.sh
Kommentarer
- Jag är inte säker på att du borde ta några förslag från den artikeln på allvar. Beviljas, den har några bra idéer, men det är uppenbarligen inte någon som brukade shell-scripting. Inte en enstaka variabel i något av exemplen citeras (!) och det föreslås att man använder UPPER C ASE-variabelnamn vilket ofta är en mycket dålig idé eftersom de kan komma i konflikt med befintliga miljöer. Dina punkter i det här svaret är vettiga, men den länkade artikeln verkar ha skrivits av någon som bara är van vid andra språk och försöker tvinga sin stil till bash.
- @terdon Jag gick tillbaka till artikeln och läste den igen. Det enda stället där författaren nämner namngivning av versaler med små bokstäver finns i ” Immutable Global Variables ”. Om du ser globala variabler som de som måste ligga inom funktion ’ s miljö, är det vettigt att göra dem kapital. På sidan noterar bash ’ s manual ’ t tillståndskonvention för variabelt fall. Även här accepterat svar säger ” vanligtvis ” och den enda ” standard ” är av Google, vilket inte ’ t representerar hela IT-branschen.
- @terdon på en annan anteckning, jag håller 100% med om att variabel citering borde ha nämnts i artikeln, och det har påpekats i kommentarerna på bloggen också. Jag skulle inte heller ’ döma någon som använder denna kodningsstil, oavsett om de ’ används till ett annat språk. Hela denna fråga och svar visar tydligt att ’ s fördelar med det, och personens ’ s grad i vilken de ’ som används till ett annat språk är förmodligen irrelevant här.
- @terdon, artikeln publicerades som en del av ” källan ” material. Jag kunde ha lagt upp allt som mina egna åsikter, men jag var bara tvungen att ge kredit att några av de saker jag lärde mig från artikeln, och att allt detta kom från att forska över tiden. Författarens ’ s länkade sida visar att de har god erfarenhet av Linux och IT i allmänhet, så jag ’ gissar att artikeln inte ’ Det visar jag verkligen inte, men jag litar på din upplevelse när det gäller Linux- och shell-skript, så du kanske har rätt.
- Att ’ är ett utmärkt svar men jag ’ vill också lägga till att variabelt omfång i Bash är funky. Av den anledningen föredrar jag att deklarera mina variabler i funktioner med
local
och ringa allt viamain()
-funktionen. Detta gör saker mycket mer hanterbara och du kan undvika en potentiellt rörig situation.
Svar
Läsbarhet är en sak. Men det finns mer till modularisering än bara detta. ( Semimodularisering är kanske mer korrekt för funktioner.)
I funktioner kan du hålla vissa variabler lokala, vilket ökar tillförlitlighet och minskar risken för saker blir trassliga.
Ett annat proffs av funktioner är återanvändbarhet . När en funktion är kodad kan den användas flera gånger i skriptet. Du kan också överföra den till ett annat skript.
Din kod kan nu vara linjär, men i framtiden kan du gå in i området multi-threading eller multi- bearbetning i Bash-världen. När du väl har lärt dig att göra saker i funktioner kommer du att vara väl rustad för steget in i parallellen.
Ytterligare en punkt att lägga till. Som Etsitpab Nioliv märker i kommentaren nedan är det lätt att omdirigera från funktioner som en sammanhängande enhet. Men det finns ytterligare en aspekt av omdirigeringar med funktioner. Omdirigeringarna kan nämligen ställas in längs funktionsdefinitionen. Till exempel:
f () { echo something; } > log
Nu krävs inga uttryckliga omdirigeringar av funktionsanropen.
$ f
Detta kan spara många repetitioner, vilket återigen ökar tillförlitligheten och hjälper till att hålla saker ordnade.
Se även
Kommentarer
- Mycket bra svara även om det vore mycket bättre om det delades in i funktioner.
- Kanske lägger du till att funktionerna låter dig importera det skriptet till ett annat skript (med
source
eller. scriptname.sh
och använd dessa funktioner som om de fanns i ditt nya skript. - Det ’ är redan täckt i ett annat svar.
- Jag uppskattar det. Men jag ’ skulle hellre låta andra människor också vara viktiga.
- Jag stod inför ett ärende idag där jag var tvungen att omdirigera en del av utskriften från ett skript till en fil (för att skicka det via e-post) istället för att eka. Jag var helt enkelt tvungen att göra minFunktion > > myFile för att omdirigera utdata från önskade funktioner. Ganska bekvämt. Kan vara relevant.
Svar
I min kommentar nämnde jag tre fördelar med funktioner:
-
De är lättare att testa och verifiera korrekthet.
-
Funktioner kan lätt återanvändas (hämtas) i framtida skript
-
Din chef gillar dem.
Och underskatta aldrig vikten av nummer 3.
Jag vill ta upp ytterligare en fråga:
… så att vi godtyckligt kan byta körordning är inte något vi vanligtvis skulle göra. Till exempel skulle du inte plötsligt vilja lägga
declare_variables
efterwalk_into_bar
, det skulle bryta saker.
För att dra nytta av att dela in kod i funktioner bör man försöka göra funktionerna så oberoende som möjligt. Om walk_into_bar
kräver en variabel som används inte någon annanstans, då ska variabeln definieras i och göras lokal till walk_into_bar
. Processen med att separera koden i funktioner och minimera deras ömsesidiga beroenden bör göra koden tydligare och enklare .
Funktioner bör helst vara lätta att testa individuellt. Om de på grund av interaktioner inte är lätta att testa är det ett tecken på att de kan dra nytta av refactoring.
Kommentarer
- Jag ’ d argumenterar för att det ’ ibland är förnuftigt att modellera och tillämpa dessa beroenden, mot refactoring för att undvika dem (eftersom om det finns enoug h av dem, och de ’ är tillräckligt håriga, det kan bara leda till ett fall där saker inte längre moduleras till funktioner alls). Ett mycket komplicerat användningsfall inspirerade en gång en ram att göra just det .
- Vad som behöver delas in i funktioner bör vara, men exemplet tar det för långt. Jag tror att den enda som verkligen stör mig är funktionen för variabeldeklaration. Globala variabler, särskilt statiska, bör definieras globalt i en kommenterad sektion tillägnad detta syfte. Dynamiska variabler ska vara lokala för funktionerna som använder och modifierar dem.
- @Xalorous I ’ har sett metoder där globala variabler initialiseras i ett förfarande, som ett mellanliggande och snabbt steg innan utvecklingen av ett förfarande som läser deras värde från en extern fil … Jag håller med om att det borde vara renare att skilja definition och initialisering men sällan måste du böja för att genomgå till fördel nummer 3
;-)
Svar
Medan jag håller helt med med återanvändbarhet , läsbarhet och att kyssa delikat cheferna men det finns en annan fördel med funktioner i bash : variabelt omfång . Som LDP visar :
#!/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.
Jag ser det inte så ofta i den verkliga världen skalskript, men det verkar som en bra idé för mer komplexa skript. Att minska sammanhållning hjälper till att undvika buggar där du klumpar in en variabel som förväntas i en annan del av koden .
Återanvändbarhet innebär ofta att skapa ett gemensamt biblioteksfunktioner och source
ingå det biblioteket i alla dina skript. Detta hjälper dem inte att springa snabbare, men det hjälper dig att skriva dem snabbare.
Kommentarer
- Få personer använder uttryckligen
local
, men jag tror att de flesta som skriver manus uppdelade i funktioner följer fortfarande designprincipen. Usignlocal
gör det bara svårare att introducera buggar. -
local
gör variabler tillgängliga för funktion och dess barn, så det ’ är riktigt trevligt att ha en variabel som kan skickas ner från funktion A, men inte tillgänglig för funktion B, som kanske vill ha variabel med samma namn men annat syfte.Så att ’ är bra för att definiera omfattningen, och som Voo sa – mindre buggar
Svar
Du delar upp koden i funktioner av samma anledning som du skulle göra för C / C ++, python, perl, ruby eller vilken programmeringsspråk som helst. Den djupare anledningen är abstraktion – du inkapslar uppgifter på lägre nivå i primitiv (funktioner) på högre nivå så att du inte behöver bry dig om hur saker görs. Samtidigt blir koden mer läsbar (och underhållbar) och programlogik blir tydligare.
Men när jag tittar på din kod tycker jag att det är ganska konstigt att ha en funktion för att deklarera variabler; det får mig verkligen att lyfta ögonbrynen.
- Underskattat svar IMHO. Föreslår du att deklarerar variablerna i
main
funktion / metod, då?
Svar
En helt annan anledning än de som redan ges i andra svar: en anledning till att denna teknik ibland används, där sulan icke-funktionsdefinitionsuttalande på toppnivå är ett samtal till main
, är att se till att manuset inte av misstag gör någonting otäckt om manuset är trunkerat. om den är piped från process A till process B (skalet), och process A avslutas av vilken anledning som helst innan den har skrivit hela skriptet. Detta är särskilt troligt att hända om process A hämtar skriptet från en fjärrresurs. Medan det av säkerhetsskäl inte är en bra idé är det något som görs, och vissa skript har modifierats för att förutse problemet.
Kommentarer
- Intressant! Men jag tycker det är oroväckande att man måste ta hand om dessa saker i vart och ett av programmen. Å andra sidan är exakt detta
main()
-mönster vanligt i Python där man använderif __name__ == '__main__': main()
i slutet av filen. - Python-idiomet har fördelen att låta andra skript
import
det aktuella skriptet utan att köramain
. Jag antar att en liknande vakt kan sättas i ett bash-skript. - @Jake Cobb Ja. Jag gör det nu i alla nya bash-skript. Jag har ett skript som innehåller en kärninfrastruktur för funktioner som används av alla nya skript. Det manuset kan hämtas eller köras. Om den köps, körs dess huvudfunktion inte. Detektering av källa vs körning sker via det faktum att BASH_SOURCE innehåller namnet på det körande skriptet. Om det ’ är detsamma som kärnskriptet körs skriptet. Annars är det ’ som hämtas.
- Nära relaterat till det här svaret använder bash enkel linjebaserad bearbetning när den körs från en fil som redan finns på disken. Om filen ändras medan skriptet körs ändras inte räknaren och div
t och den ’ fortsätter på fel rad. Inkapsling av allt i funktioner säkerställer att ’ laddas in i minnet innan du kör något, så att filen ändras ’ t påverkar den.
Svar
Några relevanta truism om programmering:
- Ditt program kommer att ändras, även om din chef insisterar på att så inte är fallet.
- Endast kod och inmatning påverkar programmets beteende.
- Att namnge är svårt.
Kommentarer börjar som ett stoppgap för att inte vara kunna uttrycka dina idéer tydligt i kod * och bli värre (eller helt enkelt fel) med förändring. Om det är möjligt uttrycka därför begrepp, strukturer, resonemang, semantik, flöde, felhantering och allt annat som är relevant för förståelsen av koden som kod.
Som sagt, Bash-funktioner har vissa problem som inte finns på de flesta språk:
- Namnavstånd är hemskt i Bash. Att glömma att använda sökordet
local
leder till att det globala namnområdet förorenas. - Användning av
local foo="$(bar)"
resulterar i förlorar utgångskoden förbar
. - Det finns ingen namngivna parametrar, så du måste komma ihåg vad
"$@"
betyder i olika sammanhang.
* Jag är ledsen om detta stötar, men efter använder kommentarer i några år och utvecklas utan dem ** i flera år är det ganska klart vilket som är överlägset.
** Att använda kommentarer för licensiering, API-dokumentation och liknande är fortfarande nödvändigt.
Kommentarer
- Jag ställde in nästan alla lokala variabler genom att deklarera dem till null i början av funktionen …
local foo=""
Ställ sedan in dem med kommandokörning för att agera på resultatet …foo="$(bar)" || { echo "bar() failed"; return 1; }
. Detta får oss snabbt ur funktionen när ett önskat värde inte kan ställas in. De lockiga hängslen är nödvändiga för att försäkra attreturn 1
bara körs vid misslyckande. - Ville bara kommentera dina punkter. Om du använder ’ subshell-funktioner ’ (funktioner avgränsade med parentes och inte lockiga parenteser), donerar du 1) ’ t måste använda lokalt men få fördelarna med lokalt, 2) Don ’ t stöta på problemet att förlora utgångskoden för kommandosubstitution i
local foo=$(bar)
lika mycket (för att du ’ inte använder lokal) 3) Don ’ t behöver oroa dig om att oavsiktligt förorena eller ändra globalt omfång 4) kan skicka ’ namngivna parametrar ’ som är ’ lokal ’ till din funktion med syntaxenfoo=bar baz=buz my-command
Svar
En process kräver en sekvens. De flesta uppgifter är sekventiella. Det är ingen mening att röra med ordern.
Men den superstora saken med programmering – som inkluderar skript – är testning. Testning, testning, testning. Vilka testskript har du för närvarande för att validera korrektheten i dina skript?
Din chef försöker vägleda dig från att vara ett skit som är lustigt till att vara programmerare. Det här är en bra väg att gå in. Människor som kommer efter dig kommer att gilla dig.
MEN. Kom alltid ihåg dina processorienterade rötter. Om det är vettigt att ha funktionerna ordnade i den sekvens som de vanligtvis utförs, gör det åtminstone som ett första pass.
Senare kommer du att se att några av dina funktioner är hantera ingång, andra ut, andra bearbeta, andra modellera data och andra manipulera data, så det kan vara smart att gruppera liknande metoder, kanske till och med flytta dem till separata filer.
Senare kan du kanske inser att du nu har skrivit bibliotek med små hjälpfunktioner som du använder i många av dina skript.
Svar
Kommentarer och avstånd kan inte komma någonstans nära läsbarheten som funktioner kan, som jag kommer att visa. Utan funktioner kan du inte se skogen för träden – stora problem gömmer sig i många detaljrader. Med andra ord kan människor inte samtidigt fokusera på de fina detaljerna och på den stora bilden. Det kanske inte är uppenbart i ett kort manus. Så länge det förblir kort kan det vara läsbart nog. Programvaran blir större, men inte mindre och det är verkligen en del av hela företagets mjukvarusystem, som säkert är mycket större, förmodligen miljontals rader.
Tänk om jag gav dig instruktioner som denna:
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)
När du hade kommit halvvägs eller till och med 5% genom, skulle du ha glömt vad de första stegen var. Du kunde kanske inte upptäcka de flesta problem, för du kunde inte se skogen för träden. Jämför med funktioner:
stand_up(); walk_to(break_room); pour(coffee); walk_to(office);
Det är verkligen mycket mer begripligt, oavsett hur många kommentarer du kan lägga i rad för rad-sekventiell version. gör det också långt mer troligt att du kommer att märka att du har glömt att göra kaffe, och glömde antagligen sit_down () i slutet. När ditt sinne tänker på detaljerna i grep och awk regexes, kan du inte tänka helheten – ”vad händer om inget kaffe görs”?
Funktioner gör att du först och främst kan se helheten, och märker att du har glömt att göra kaffe (eller att någon kanske föredrar te). Vid en annan tid, i en annan sinnesstil, oroar du dig för den detaljerade implementeringen.
Det finns också andra fördelar som diskuteras i Andra svar, naturligtvis. En annan fördel som inte tydligt anges i de andra svaren är att funktioner ger en garanti som är viktigt för att förhindra och fixa buggar. Om du upptäcker att någon variabel $ foo i rätt funktion walk_to () var fel, vet du att du bara behöver titta på de andra 6 raderna i den funktionen för att hitta allt som kan ha påverkats av det problemet och allt som kan har orsakat att det är fel. Utan (korrekta) funktioner kan allt och allt i hela systemet vara en orsak till att $ foo är felaktigt, och allt och allt kan påverkas av $ foo. Därför kan du inte säkert fixa $ foo utan att granska varje enskild rad i programmet igen. Om $ foo är lokal för en funktion kan du garantera att alla ändringar är säkra och korrekta genom att bara kontrollera den funktionen.
Kommentarer
- Detta är ’ t
bash
syntax.Det ’ är dock synd; Jag tror inte ’ att det finns ett sätt att skicka inmatning till sådana funktioner. (dvs.pour();
<coffee
). Det ser mer ut somc++
ellerphp
(tror jag). - @ tjt263 utan parenteser, det ’ s bash-syntax: häll kaffe. Med parens är det ’ nästan alla andra språk. 🙂
Svar
Time is money
Det finns andra bra svar som sprider ljus över de tekniska skälen att skriva modulärt ett manus, eventuellt lång, utvecklad i en arbetsmiljö, utvecklad för att användas av en grupp personer och inte bara för eget bruk.
Jag vill fokusera på en förvänta sig: i en arbetsmiljö ”tid är pengar” . Så frånvaron av buggar och prestanda för din kod utvärderas tillsammans med läsbarhet , testbarhet, underhållsbarhet, refactorability, återanvändbarhet …
Skriv i ” moduler ” en kod minskar lästiden som inte bara behövs av kodaren utan även den tid som testarna eller av chefen. Observera dessutom att tiden för en chef vanligtvis betalas mer än tiden för en kodare och att din chef kommer att utvärdera kvaliteten på ditt jobb.
Dessutom skriver du i oberoende ”moduler” en kod (till och med ett bash-skript) gör att du kan arbeta ”parallellt” med annan del av ditt team förkortar den totala produktionstiden och använder i bästa fall den enskilda expertis, för att granska eller skriva om en del utan biverkningar på de andra, för att återvinna koden du just har skrivit ”som den är” för ett annat program / skript, för att skapa bibliotek (eller bibliotek för utdrag), för att minska den totala storleken och tillhörande sannolikhet för fel, för att felsöka och testa grundligt varje enskild del … och naturligtvis kommer det att organiseras logiskt avsnitt ditt program / skript och förbättra dess läsbarhet. Allt som sparar tid och så pengar. Nackdelen är att du måste hålla dig till standarder och kommentera dina funktioner (som du inte har att göra i en arbetsmiljö).
Att följa en standard kommer att sakta ner ditt arbete i början men det kommer att påskynda alla andras arbete (och din också) efteråt. När samarbetet växer i antal involverade personer blir detta faktiskt ett oundvikligt behov. Så till exempel, även om jag tror att de globala variablerna måste definieras globalt och inte i en funktion, kan jag förstå en standard som inizialiserar dem i en funktion som heter declare_variables()
kallas alltid i första raden i main()
en …
Sist men inte minst, underskatta inte möjligheten i modern källkod redaktörer för att visa eller dölja selektivt separata rutiner ( Kodvikning ). Detta kommer att hålla koden kompakt och fokusera på att användaren sparar tid igen.
Här ovan kan du se hur det viks ut endast walk_into_bar()
-funktionen. Till och med av de andra var 1000 rader vardera, du kunde fortfarande hålla kontroll över alla koder på en enda sida. Observera att det är vikat även det avsnitt där du går för att deklarera / initiera variablerna.
Svar
En annan anledning som ofta förbises är bash ”s syntax parsing:
set -eu echo "this shouldn"t run" { echo "this shouldn"t run either"
Detta skript innehåller uppenbarligen ett syntaxfel och bash borde inte alls köra det, eller hur? Fel.
~ $ bash t1.sh this shouldn"t run t1.sh: line 7: syntax error: unexpected end of file
Om vi slog in koden i en funktion skulle det inte hända:
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
Svar
Bortsett från orsakerna i andra svar:
- Psykologi: En programmerare vars produktivitet mäts i kodrader kommer att ha ett incitament att skriva onödigt omfattande kod. Ju mer hantering är med fokus på kodrader, desto mer incitament har programmeraren att utöka sin kod med onödig komplexitet. Detta är oönskat eftersom ökad komplexitet kan leda till ökade underhållskostnader och ökad ansträngning som krävs för felkorrigering.
Kommentarer
- Det är inte så dåligt svar, som nedröstningarna säger. Obs: agc säger, det här är också en möjlighet, och ja, det är det. Han ’ t säger att det skulle vara den enda möjligheten, och anklagar inte ’ t endast någon. Även om jag tycker att idag är nästan okänt är en direkt ” kodrad ” – > ” $$ ” stiluppdrag, på indirekt betyder det att det är ganska vanligt att ja, massan av den producerade koden räknas av ledarna / bossar.
main()
överst och lägger tillmain "$@"
längst ner för att kalla det. Det låter dig se den höga nivå skriptlogik först när du öppnar den.local
– detta ger variabelt omfattning vilket är oerhört viktigt i alla icke-triviala skript.