De ce să scriem un întreg script bash în funcții?

La serviciu, scriu frecvent scripturi bash. Supervizorul meu a sugerat ca întregul script să fie împărțit în funcții, similar cu următorul exemplu:

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

Există vreun alt motiv pentru a face acest lucru în afară de „lizibilitate” , ceea ce cred că ar putea fi la fel de bine stabilit cu alte câteva comentarii și o oarecare distanță între linii?

Face scriptul să ruleze mai eficient (de fapt, m-aș aștepta la opus, dacă este ceva), sau face este mai ușor să modificați codul dincolo de potențialul de lizibilitate menționat mai sus? Sau este într-adevăr doar o preferință stilistică?

Rețineți că, deși scriptul nu-l demonstrează bine, „ordinea de rulare” a funcțiilor din scripturile noastre actuale tinde să fie foarte liniară – walk_into_bar depinde de lucrurile pe care le-a făcut i_am_foo și do_baz acționează asupra lucrurilor configurate de walk_into_bar – deci posibilitatea de a schimba arbitrar ordinea de rulare nu este ceva ce am face în general. De exemplu, nu ați dori brusc să puneți declare_variables după walk_into_bar, care ar rupe lucrurile.

exemplu despre cum aș scrie scriptul de mai sus ar fi:

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

Comentarii

  • Îmi place șef. În scripturile mele am pus și main() în partea de sus și adaug main "$@" în partea de jos pentru a o apela. Asta vă permite să vedeți logica scriptului de nivel primul lucru când îl deschideți.
  • Nu sunt de acord cu ideea că lizibilitatea poate ” să fie la fel de bine stabilită cu încă câteva comentarii și o oarecare distanță între linii . ” Cu excepția poate pentru ficțiune, nu aș vrea ‘ să vreau să mă ocup de o carte care nu ‘ t are un cuprins și nume descriptive pentru fiecare capitol și secțiune. În limbaje de programare, acesta este ‘ tipul de lizibilitate pe care funcțiile îl pot oferi, un nd comentariu ‘ s poate ‘ t.
  • Rețineți că variabilele declarate în funcții ar trebui declarate – aceasta oferă o variabilă scop , care este extrem de important în orice script non-banal.
  • Nu sunt de acord cu șeful tău. Dacă trebuie să împărțiți scriptul în funcții, probabil că nu ar trebui ‘ să scrieți în primul rând un script shell. Scrieți un program în schimb.
  • Funcțiile sunt pentru procesele care se repetă, fie în cadrul scriptului, fie în mai multe scripturi. De asemenea, permit punerea în aplicare a unor metodologii uniforme. De exemplu, folosind o funcție pentru a scrie pe syslog. Atâta timp cât toată lumea folosește aceeași funcție, intrările dvs. din syslog sunt mai consistente. Funcțiile cu o singură utilizare, cum ar fi exemplul dvs., complică inutil scriptul. În unele cazuri, ele introduc probleme (variabile cu scop).

Răspuns

Am început să folosesc același lucru stilul de programare bash după ce ați citit postarea pe blog a lui Kfir Lavi „Programare defensivă pentru bash” . El ne oferă destul de multe motive bune, dar personal consider că acestea sunt cele mai importante:

  • procedurile devin descriptive: este mult mai ușor să ne dăm seama ce se presupune că o anumită parte a codului de făcut. În loc de perete de cod, vedeți „Oh, funcția find_log_errors citește acel fișier jurnal pentru erori”. Comparați-l cu găsirea unei mulțimi de linii awk / grep / sed care folosiți Dumnezeu știe ce tip de regex în mijlocul unui script lung – nu aveți idee ce face acolo, cu excepția cazului în care există comentarii.

  • puteți depana funcții prin încadrarea în set -x și set +x. Odată ce știți că restul codului funcționează bine, puteți folosi acest truc pentru a vă concentra asupra depanării numai a funcției specifice. Sigur, puteți include părți ale scriptului, dar dacă „este o porțiune lungă? Este mai ușor să faceți așa ceva:

     set -x parse_process_list set +x 
  • utilizarea tipăririi cu cat <<- EOF . . . EOF. L-am folosit de câteva ori pentru a face codul meu mult mai profesionist. În plus, funcția parse_args() cu funcția getopts este destul de convenabilă. Din nou, acest lucru ajută la lizibilitate, în loc să împingă totul în script ca un perete uriaș de text. Este de asemenea convenabil să le reutilizezi.

Și, evident, este mult mai mult lizibil pentru cineva care cunoaște C sau Java sau Vala, dar are o experiență limitată. În ceea ce privește eficiența, nu există multe din ceea ce puteți face – însuși nu este limbajul cel mai eficient și oamenii preferă perl și python când vine vorba de viteză și eficiență.Cu toate acestea, puteți nice o funcție:

nice -10 resource_hungry_function 

Comparativ cu apelarea drăguță pe fiecare linie de cod, acest lucru scade o mulțime de tastare ȘI poate fi utilizat în mod convenabil atunci când doriți ca doar o parte din script să ruleze cu prioritate mai mică.

Rularea funcțiilor în fundal, în opinia mea, vă ajută și atunci când doriți să aveți întreg o grămadă de declarații pentru a rula în fundal.

Unele exemple în care am „folosit acest stil:

Comentarii

  • Nu sunt sigur că ar trebui să luați foarte în serios vreo sugestie din articolul respectiv. Desigur, are câteva idei bune, dar în mod clar nu este cineva obișnuit să shell scripting. Nu este un single din oricare dintre exemple este citată (!) și sugerează utilizarea UPPER C Numele variabilelor ASE, care este adesea o idee foarte proastă, deoarece acestea pot intra în conflict cu vars-urile existente. Punctele dvs. din acest răspuns au sens, dar articolul legat pare să fi fost scris de cineva care tocmai este obișnuit cu alte limbi și încearcă să forțeze stilul lor pe bash.
  • @terdon M-am întors la articol și l-am recitit. Singurul loc în care autorul menționează denumirea variabilelor majuscule este în ” Variabile globale imuabile „. Dacă considerați variabilele globale ca fiind cele care trebuie să se afle în mediul funcțional ‘, atunci este logic să le faceți majuscule. Pe o notă laterală, manualul bash ‘ nu are ‘ t convenție de stat pentru variabile. Chiar și aici răspuns acceptat spune ” de obicei ” și singurul ” standard ” este de la Google, care nu ‘ nu reprezintă întreaga industrie IT.
  • @terdon într-o altă notă, sunt de acord 100% că citarea variabilă ar fi trebuit menționată în articol și a fost subliniată și în comentariile de pe blog. De asemenea, nu aș ‘ judeca pe cineva care utilizează acest stil de codificare, indiferent dacă ‘ este folosit sau nu în altă limbă. Toată această întrebare și răspunsuri arată clar că există ‘ avantajele acesteia și gradul persoanei ‘ în care ‘ folosit în altă limbă este probabil irelevant aici.
  • @terdon, articolul a fost postat ca parte a ” sursă ” material. Aș fi putut să postez totul ca pe propriile păreri, dar a trebuit doar să cred că unele dintre lucrurile pe care le-am învățat din articol și că toate acestea provin din cercetări de-a lungul timpului. Pagina linkedin a autorului ‘ arată că au o experiență bună cu Linux și IT în general, așa că ‘ presupun că articolul nu ‘ nu arată cu adevărat asta, dar am încredere în experiența dvs. când vine vorba de Linux și shell scripting, așa că s-ar putea să aveți dreptate. „>

este un răspuns excelent, dar îmi place să adaug că domeniul de aplicare variabil în Bash este funky. Din acest motiv, prefer să declar variabilele mele în interiorul funcțiilor folosindlocalși apelând totul prin intermediul funcțieimain(). Acest lucru face lucrurile mult mai ușor de gestionat și puteți evita o situație potențial dezordonată.

Răspuns

Citibilitatea este un lucru. Dar există mai mult decât modularizare decât doar asta. ( Semi-modularizarea este poate mai corectă pentru funcții.)

În funcții puteți menține locale unele variabile, ceea ce crește fiabilitatea , scăzând șansa de lucrurile se încurcă.

Un alt pro al funcțiilor este reutilizarea . Odată ce o funcție este codificată, aceasta poate fi aplicată de mai multe ori în script. Puteți, de asemenea, să îl portați pe un alt script.

Codul dvs. acum poate fi liniar, dar în viitor puteți intra în domeniul multi-threading sau multi- procesare în lumea Bash. Odată ce veți învăța să faceți lucruri în funcții, veți fi bine echipat pentru a intra în paralel.

Încă un punct de adăugat. După cum observă Etsitpab Nioliv în comentariul de mai jos, este ușor de redirecționat de la funcții ca entitate coerentă. Dar există încă un aspect al redirecționărilor cu funcții. Anume, redirecționările pot fi setate de-a lungul definiției funcției. De ex .:

f () { echo something; } > log 

Acum nu sunt necesare redirecționări explicite pentru apelurile de funcții.

$ f 

Acest lucru poate economisi multe repetări, ceea ce crește din nou fiabilitatea și ajută la menținerea lucrurilor în ordine.

Vezi și

Comentarii

  • Foarte bine răspuns, deși ar fi mult mai bine dacă ar fi împărțit în funcții.
  • Poate adăugați că funcțiile vă permit să importați acel script într-un alt script (utilizând source sau . scriptname.sh și utilizați acele funcții ca și cum ar fi în noul dvs. script.
  • ‘ sunt deja acoperite într-un alt răspuns.
  • Apreciez acest lucru. Dar am ‘ prefer să las și alte persoane să fie importante.
  • M-am confruntat cu un caz astăzi, unde a trebuit să redirecționez o parte din ieșirea unui script către un fișier (pentru a-l trimite prin e-mail) în loc să fac ecou. Trebuia pur și simplu să fac funcția mea > > myFile pentru a redirecționa ieșirea funcțiilor dorite. Destul de convenabil. Poate fi relevant.

Răspuns

În comentariul meu, am menționat trei avantaje ale funcțiilor:

  1. Sunt mai ușor de testat și de verificat corectitudinea.

  2. Funcțiile pot fi ușor reutilizate (obținute) în scripturi viitoare

  3. Șefului tău îi plac.

Și, nu subestimați niciodată importanța numărului 3.

Aș dori să abordez încă o problemă:

… deci posibilitatea de a schimba arbitrar ordinea de rulare nu este ceva ce am face în general. De exemplu, nu ați dori brusc să puneți declare_variables după walk_into_bar, care ar rupe lucrurile.

Pentru a beneficia de avantajul divizării codului în funcții, ar trebui să încercați să faceți funcțiile cât mai independente posibil. Dacă walk_into_bar necesită o variabilă care nu este utilizat în altă parte, atunci variabila respectivă ar trebui definită și localizată la walk_into_bar. Procesul de separare a codului în funcții și de minimizare a interdependențelor acestora ar trebui să facă codul mai clar și mai simplu .

În mod ideal, funcțiile ar trebui să fie ușor de testat individual. Dacă, din cauza interacțiunilor, acestea nu sunt ușor de testat, atunci acesta este un semn că ar putea beneficia de refactorizare.

Comentarii

  • ‘ susțin că uneori este rezonabil de modelat ‘ și aplică aceste dependențe, față de refactoring pentru a le evita (deoarece dacă există h dintre ele și ‘ sunt suficient de păroase, ceea ce poate duce doar la un caz în care lucrurile nu mai sunt deloc modularizate în funcții). Un caz de utilizare foarte complicat a inspirat odată un cadru pentru a face exact asta .
  • Ceea ce trebuie împărțit în funcții ar trebui să fie, dar exemplul o duce prea departe. Cred că singura care mă dă peste cap este funcția de declarație variabilă. Variabilele globale, în special cele statice, ar trebui definite la nivel global într-o secțiune comentată dedicată acestui scop. Variabilele dinamice ar trebui să fie locale la funcțiile care le utilizează și le modifică.
  • @Xalorous Am ‘ am văzut o practică în care variabilele globale sunt inițializate într-o procedură, ca un pas intermediar și rapid înainte de dezvoltarea unei proceduri care le citește valoarea dintr-un fișier extern … Sunt de acord că ar trebui să fie mai curat să separați definiția și inițializarea, dar rareori trebuie să vă aplecați pentru a trece avantaj numărul 3 ;-)

Răspuns

Deși sunt total de acord cu reutilizarea , lizibilitatea și sărutarea delicată a șefilor, dar există un alt avantaj al funcțiilor în : domeniu variabil . După cum arată 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. 

Nu văd acest lucru foarte des în lumea reală script-uri shell, dar pare o idee bună pentru scripturi mai complexe. Reducerea coerenței ajută la evitarea erorilor în care „claperați” o variabilă așteptată într-o altă parte a codului .

Reutilizarea înseamnă adesea crearea unei biblioteci comune de funcții și source introducerea acelei biblioteci în toate scripturile dvs. Acest lucru nu le va ajuta să ruleze mai repede, dar vă va ajuta să le scrieți mai repede.

Comentarii

  • Puțini oameni folosesc în mod explicit local, dar cred că majoritatea oamenilor care scriu scripturi împărțite în funcții respectă în continuare principiul de proiectare. Usign local simplifică introducerea bugurilor. >
  • local pune la dispoziție variabile pentru a funcționa și a copiilor săi, deci este ‘ foarte frumos să ai o variabilă care poate fi transmisă în jos de la funcția A, dar indisponibil pentru funcția B, care ar putea dori să aibă variabilă cu același nume, dar cu scop diferit.Așa că ‘ este bun pentru a defini domeniul de aplicare și, așa cum a spus Voo – mai puține bug-uri

Răspunde

Divizați codul în funcții din același motiv pentru care ați face acest lucru pentru C / C ++, python, perl, ruby sau orice cod de limbaj de programare. Motivul mai profund este abstractizarea – încapsulați sarcini de nivel inferior în primitive (funcții) de nivel superior, astfel încât să nu aveți nevoie să vă deranjați cum se fac lucrurile. În același timp, codul devine mai ușor de citit (și mai ușor de întreținut) și logica programului devine mai clară.

Cu toate acestea, uitându-mă la codul tău, mi se pare destul de ciudat să ai o funcție de declarare a variabilelor; acest lucru mă face să mă ridic cu o sprâncene.

  • Răspuns subestimat IMHO. Sugerați să declarați variabilele din funcția / metoda main?

Răspuns

Un motiv complet diferit de cel dat deja în alte răspunsuri: un motiv pentru care se folosește uneori această tehnică, unde singura instrucțiunea non-function-definition la nivel superior este un apel către main, este să vă asigurați că scriptul nu face în mod accidental nimic urât dacă scriptul este trunchiat. Scriptul poate fi trunchiat dacă este canalizat de la procesul A la procesul B (shell), iar procesul A se încheie din orice motiv înainte de a termina de scris întregul script. Acest lucru se va întâmpla în special dacă procesul A preia scriptul dintr-o resursă la distanță. În timp ce, din motive de securitate, aceasta nu este o idee bună, este ceva ce se face, iar unele scripturi au fost modificate pentru a anticipa problema.

Comentarii

  • Interesant! Dar mi se pare îngrijorător faptul că trebuie să ai grijă de aceste lucruri în fiecare dintre programe. Pe de altă parte, exact acest model main() este obișnuit în Python unde se folosește if __name__ == '__main__': main() la sfârșitul fișierului.
  • idiomul Python are avantajul de a permite altor scripturi import scriptul curent fără a rula main. Presupun că un gardian similar ar putea fi pus într-un script bash.
  • @Jake Cobb Da. Acum fac asta în toate scripturile noi bash. Am un script care conține o infrastructură de bază a funcțiilor utilizate de toate scripturile noi. Acest script poate fi obținut sau executat. Dacă este obținut, funcția sa principală nu este executată. Detectarea sursei vs execuției se face prin faptul că BASH_SOURCE conține numele scriptului de executare. Dacă ‘ este la fel ca scriptul de bază, scriptul este executat. În caz contrar, ‘ este obținut.
  • În strânsă legătură cu acest răspuns, bash folosește procesare simplă pe linie atunci când rulează dintr-un fișier deja pe disc. Dacă fișierul se modifică în timp ce rulează scriptul, contorul de linie nu ‘ se schimbă și ‘ va continua pe linia greșită. Incapsularea tuturor funcțiilor asigură ‘ toate încărcate în memorie înainte de a rula ceva, astfel încât modificarea fișierului nu îl afectează. „div. li>

Răspuns

Unele truisme relevante despre programare:

  • Programul dvs. se va schimba, chiar dacă șeful dvs. insistă că nu este cazul.
  • Numai codul și intrarea afectează comportamentul programului.
  • Denumirea este dificilă.

Comentariile încep ca un stop-gap pentru că nu sunt capabil să vă exprimați clar ideile în cod * și să vă înrăutățiți (sau pur și simplu să greșiți) odată cu schimbarea. Prin urmare, dacă este posibil, exprimați concepte, structuri, raționament, semantică, flux, gestionarea erorilor și orice altceva relevant pentru înțelegerea codului ca cod.

Acestea fiind spuse, Funcțiile Bash au unele probleme care nu au fost găsite în majoritatea limbilor:

  • Spațiul de nume este teribil în Bash. De exemplu, uitarea de a utiliza cuvântul cheie local duce la poluarea spațiului de nume global.
  • Utilizarea local foo="$(bar)" are ca rezultat pierzând codul de ieșire al bar .
  • Nu există parametrii numiți, deci trebuie să aveți în vedere ce înseamnă "$@" în contexte diferite.

* Îmi pare rău dacă acest lucru ofensează, dar după folosirea comentariilor pentru câțiva ani și dezvoltarea fără ele ** pentru mai mulți ani este destul de clar care este superior.

** Este încă necesară utilizarea comentariilor pentru licențiere, documentația API și altele asemenea.

Comentarii

  • Am setat aproape toate variabilele locale declarându-le nule la începutul funcției …local foo="" Apoi setați-le folosind executarea comenzii pentru a acționa asupra rezultatului … foo="$(bar)" || { echo "bar() failed"; return 1; }. Acest lucru ne scoate rapid din funcție atunci când nu se poate seta o valoare necesară. Aparatele dentare sunt necesare pentru a vă asigura că return 1 este executat numai în caz de eșec.
  • Am vrut doar să comentez punctele dvs. glonț. Dacă utilizați ‘ funcții sub-shell ‘ (funcții delimitate de paranteză și nu paranteze curlate), 1) nu ‘ nu trebuie să utilizați local, dar obțineți avantajele de local, 2) Nu ‘ nu întâmpinați problema pierderii codului de ieșire al substituției comenzii în local foo=$(bar) la fel de mult (deoarece ‘ nu utilizați local) 3) Nu ‘ nu trebuie să vă faceți griji despre poluarea accidentală sau schimbarea scopului global 4) pot trece în ‘ parametrii numiți ‘ care sunt ‘ local ‘ funcției dvs. utilizând sintaxa foo=bar baz=buz my-command

Răspuns

Un proces necesită o secvență. Majoritatea sarcinilor sunt secvențiale. Nu are sens să te încurci cu comanda.

Dar cel mai mare lucru legat de programare – care include scriptarea – este testarea. Testare, testare, testare. Ce scripturi de testare aveți în prezent pentru a valida corectitudinea scripturilor dvs.?

Șeful dvs. încearcă să vă ghideze de la a fi un script de copil până la a fi programator. Aceasta este o direcție bună pentru a intra. Oamenii care vin după tine vă vor plăcea.

DAR. Amintiți-vă întotdeauna rădăcinile dvs. orientate spre proces. Dacă are sens să aveți funcțiile ordonate în secvența în care sunt executate de obicei, atunci faceți asta, cel puțin ca o primă trecere.

Mai târziu, veți vedea că unele dintre funcțiile dvs. sunt gestionarea intrărilor, a altor ieșiri, a altor procesare, a altor modele de date și a altor manipularea datelor, deci poate fi inteligent să grupați metode similare, poate chiar mutându-le în fișiere separate.

Mai târziu, puteți îți dai seama că acum ai scris biblioteci cu funcții de ajutor mic pe care le folosești în multe dintre scripturile tale.

Răspuns

Comentarii iar spațierea nu poate nu ajunge aproape de lizibilitatea pe care funcțiile o pot, după cum voi demonstra. Fără funcții, nu puteți vedea pădurea pentru copaci – mari probleme se ascund printre multe linii de detalii. Cu alte cuvinte, oamenii nu se pot concentra simultan pe detaliile fine și pe imaginea de ansamblu. Acest lucru s-ar putea să nu fie evident într-un scenariu scurt; atâta timp cât rămâne scurt, poate fi suficient de lizibil. Software-ul devine totuși mai mare, nu mai mic , și cu siguranță face parte din întregul sistem software al companiei dvs., care este cu siguranță mult mai mare, probabil milioane de linii.

Luați în considerare dacă v-am dat instrucțiuni de genul acesta:

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) 

Până când ați ajuns la jumătate sau chiar 5%, ați fi uitat care au fost primii pași. Nu ați putut găsi cele mai multe probleme, deoarece nu ați putut vedea pădurea pentru copaci. Comparați cu funcțiile:

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

Acest lucru este cu siguranță mult mai ușor de înțeles, indiferent de câte comentarii ați putea pune în versiunea secvențială linie cu linie. face, de asemenea, mult mai probabil că veți observa că ați uitat să faceți cafeaua și probabil că am uitat sit_down () la sfârșit. Când mintea ta se gândește la detaliile grege și regex awk, nu poți să te gândești la o imagine de ansamblu – „ce se întâmplă dacă nu se face cafea”?

Funcțiile îți permit în primul rând să vezi imaginea de ansamblu, și observați că ați uitat să preparați cafeaua (sau că cineva ar putea prefera ceaiul). În altă perioadă, într-un cadru de spirit diferit, vă faceți griji cu privire la implementarea detaliată.

Există și alte beneficii discutate în alte răspunsuri, desigur. Un alt beneficiu care nu este precizat în celelalte răspunsuri este că funcțiile oferă o garanție care este importantă în prevenirea și remedierea erorilor. Dacă descoperiți că o variabilă $ foo în funcția corectă walk_to () a fost greșită, știți că trebuie doar să vă uitați la celelalte 6 linii ale acelei funcții pentru a găsi tot ceea ce ar fi putut fi afectat de acea problemă și tot ceea ce ar putea au făcut să fie greșit. Fără funcții (adecvate), orice și tot din întregul sistem ar putea fi o cauză a faptului că $ foo este incorect și orice și orice ar putea fi afectat de $ foo. Prin urmare, nu puteți remedia în siguranță $ foo fără a reexamina fiecare linie a programului. Dacă $ foo este local pentru o funcție, puteți garanta că toate modificările sunt sigure și corecte verificând doar acea funcție.

Comentarii

  • Aceasta nu este sintaxa ‘ t bash.Totuși, ‘ este o rușine; Nu ‘ nu cred că există o modalitate de a transmite intrarea unor astfel de funcții. (adică pour(); < coffee). Arată mai mult ca c++ sau php (cred).
  • @ tjt263 fără paranteze, este ‘ s sintaxă bash: toarnă cafea. Cu parens, ‘ este aproape orice altă limbă. 🙂

Răspuns

Timpul este bani

Există alte răspunsuri bune care răspândesc motivele tehnice pentru a scrie modular un script, potențial lung, dezvoltat într-un mediu de lucru, dezvoltat pentru a fi utilizat de un grup de persoane și nu numai pentru propria dvs. utilizare.

Vreau să concentrați-vă pe pe o singură așteptare: într-un mediu de lucru „timpul înseamnă bani” . Deci, absența erorilor și performanțele codului dvs. sunt evaluate împreună cu lizibilitate , testabilitate, mentenabilitate, refactorabilitate, reutilizare

Scriere în ” module „ un cod va reduce timpul de citire necesar nu numai de coder însuși, ci chiar și de timpul folosit de testeri sau de șeful. Mai mult, rețineți că timpul unui șef este de obicei plătit mai mult decât timpul unui coder și că șeful dvs. va evalua calitatea locului dvs. de muncă.

Mai mult, scriind în independent „module” un cod (chiar și un script bash) vă va permite să lucrați în „paralel” cu altă componentă a echipei dvs. scurtând timpul total de producție și folosind în cel mai bun caz expertiza individuală, pentru a revizui sau rescrie o parte fără efecte secundare asupra celorlalte, pentru a recicla codul pe care tocmai l-ați scris „așa cum este” pentru un alt program / script, pentru a crea biblioteci (sau biblioteci de fragmente), pentru a reduce dimensiunea generală și probabilitatea aferentă de erori, pentru a depana și testa în detaliu fiecare parte … și, desigur, se va organiza în logică secționați programul / scriptul și îmbunătățiți lizibilitatea acestuia. Toate lucrurile care vă vor economisi timp și așa bani. Dezavantajul este că trebuie să respectați standardele și să vă comentați funcțiile (că nu aveți mai puțin de făcut într-un mediu de lucru).

A adera la un standard vă va încetini munca la început, dar va accelera munca tuturor celorlalți (și a ta și a ta) după aceea. Într-adevăr, atunci când colaborarea crește în număr de persoane implicate, aceasta devine o nevoie inevitabilă. De exemplu, chiar dacă cred că variabilele globale trebuie definite global și nu într-o funcție, pot înțelege un standard care le inițializează într-o funcție numită declare_variables() numit întotdeauna în prima linie a main()

Nu în ultimul rând, nu subestimați posibilitatea în codul sursă modern editori pentru a afișa sau pentru a ascunde rutine separate selectiv ( Plierea codului ). Acest lucru va păstra compact codul și va concentra utilizatorul economisind din nou timp.

introduceți descrierea imaginii aici

Aici mai sus puteți vedea cum este desfăcută doar funcția walk_into_bar(). Chiar și dintre celelalte aveau 1000 de linii fiecare, puteți păstra tot controlul asupra codului într-o singură pagină. Rețineți că este pliat chiar și secțiunea în care mergeți pentru a declara / inițializa variabilele.

Răspuns

Un alt motiv ceea ce este adesea trecut cu vederea este analiza sintaxei bash:

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

Acest script conține în mod evident o eroare de sintaxă și bash nu ar trebui să-l ruleze deloc, nu? Greșit.

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

Dacă am înfășura codul într-o funcție, acest lucru nu s-ar întâmpla:

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ăspuns

În afară de motivele prezentate în alte răspunsuri:

  1. Psihologie: un programator a cărui productivitate este măsurată în linii de cod va avea un stimulent pentru a scrie cod inutil în mod inutil. Cu cât este mai mult managementul concentrându-se pe liniile de cod, cu atât programatorul are mai multe stimulente pentru a-și extinde codul cu o complexitate inutilă. Acest lucru nu este de dorit, deoarece complexitatea crescută poate duce la creșterea costurilor de întreținere și la efortul necesar pentru remedierea erorilor.

Comentarii

  • Nu este un răspuns atât de rău, cum spun voturile negative. Notă: agc spune că, de asemenea, aceasta este o posibilitate și da, este. El nu ‘ nu spune că ar fi singura posibilitate și nu ‘ nu acuză pe nimeni, doar afirmă faptele. Deși cred că astăzi este aproape nemaiauzit un ” linie de cod direct ” – > ” $$ ” loc de muncă în stil, în mod indirect, este destul de obișnuit, că da, masa codului produs este contată de lideri / șefi.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *