Miksi kirjoittaa koko bash-komentosarja funktioihin?

Työssä kirjoitan bash-komentosarjoja usein. Esimieheni on ehdottanut, että koko komentosarja jaetaan funktioihin seuraavan esimerkin tavoin:

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

Onko tähän mitään muuta syytä kuin ”luettavuus” , joka mielestäni voisi olla yhtä vakiintunut muutamalla lisäkommentilla ja rivivälillä?

Tekeekö se komentosarjan toimivan tehokkaammin (odotan itse asiassa päinvastaista, jos mitään) vai tekeekö se onko koodia helpompi muokata edellä mainitun luettavuuspotentiaalin ulkopuolella? Vai onko se oikeastaan vain tyylinen mieltymys?

Huomaa, että vaikka komentosarja ei osoita sitä hyvin, varsinaisten komentosarjojemme toimintojen ”ajojärjestys” on yleensä hyvin lineaarinen – walk_into_bar riippuu jutuista, jotka i_am_foo on tehnyt, ja do_baz vaikuttaa walk_into_bar – joten juoksujärjestyksen vaihtaminen mielivaltaisesti ei ole jotain, mitä yleensä teemme. Esimerkiksi, et halua yhtäkkiä haluta laittaa declare_variables walk_into_bar: n jälkeen, mikä rikkoo asioita.

An Esimerkki siitä, miten kirjoitan yllä olevan komentosarjan, olisi:

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

Kommentit

  • Pidän sinun pomo. Laitoin komentosarjoihini myös main() yläosaan ja lisäämällä alareunaan main "$@" kutsua sitä. Näin näet korkean tason komentologiikka on ensimmäinen asia, kun avaat sen.
  • En ole samaa mieltä käsityksestä, jonka mukaan luettavuus voidaan ” vahvistaa yhtä hyvin muutamalla lisäkommentilla ja rivivälillä. . ” Paitsi ehkä kaunokirjallisuutta, en halua ’ halua käsitellä kirjaa, joka ei ’ t: llä on sisällysluettelo ja kuvaavat nimet kullekin luvulle ja osalle. Ohjelmointikielissä ’ on sellainen luettavuus, jonka toiminnot voivat tarjota, nd kommentti ’ s voivat ’ t.
  • Huomaa, että funktioissa ilmoitetut muuttujat on ilmoitettava local – tämä tarjoaa muuttuvan laajuuden , joka on uskomattoman tärkeä missä tahansa ei-triviaalissa skriptissä.
  • En ole samaa mieltä pomosi kanssa. Jos sinun on jaoteltava komentosarja funktioksi, sinun ei todennäköisesti ’ t tarvitse kirjoittaa komentotulkkikomentoa. Kirjoita sen sijaan ohjelma.
  • Funktiot ovat prosesseille, jotka toistetaan joko komentosarjassa tai useammassa kuin yhdessä komentosarjassa. Ne mahdollistavat myös yhtenäisten menetelmien käyttöönoton. Esim. Toiminnon avulla kirjoittaa syslogiin. Niin kauan kuin kaikki käyttävät samaa toimintoa, syslog-merkinnät ovat johdonmukaisempia. Kertakäyttöiset toiminnot, kuten esimerkkisi, monimutkaistavat komentosarjaa. Joissakin tapauksissa he ottavat esiin kysymyksiä (muuttujan laajuus).

Vastaus

Olen aloittanut saman käytön bash-ohjelmoinnin tyyli lukemalla Kfir Lavi -blogiviesti ”Defensive Bash Programming” . Hän antaa melkoisen hyvän syyn, mutta henkilökohtaisesti pidän näitä tärkeimpinä:

  • menettelyistä tulee kuvaavia: on paljon helpompaa selvittää, mistä tietystä koodin osasta oletetaan tehdä. Seinäkoodin sijaan näet ”Oh, find_log_errors -toiminto lukee lokitiedoston virheiden varalta”. Vertaa sitä monien awk / grep / sed-rivien löytämiseen käytä jumala tietää, minkä tyyppinen regex keskellä pitkää komentosarjaa – et ole aavistustakaan mitä se tekee siellä, ellei siellä ole kommentteja.

  • voit debug-toimintoja liittämällä osiin set -x ja set +x. Kun tiedät muun koodin toimivan kunnolla, voit käyttää tätä temppua keskittyäksesi vain kyseisen toiminnon virheenkorjaukseen. Toki, voit liittää käsikirjoituksen osia, mutta entä jos se on pitkä osa? On helpompaa tehdä jotain tällaista:

     set -x parse_process_list set +x 
  • tulostuskäyttö cat <<- EOF . . . EOF -merkillä. Olen käyttänyt sitä melko monta kertaa koodin tekemiseksi paljon ammattimaisemmaksi. Lisäksi parse_args() toiminnolla getopts on melko kätevä. Jälleen tämä auttaa luettavuudessa sen sijaan, että työntäisit kaiken käsikirjoitukseen jättimäisenä tekstiseinänä. Niitä on myös kätevää käyttää uudelleen.

Ja tämä on tietysti paljon enemmän luettavissa jollekulle, joka tuntee C: n, Java: n tai Valan, mutta jolla on rajallinen kokemus bashista. Tehokkuuden suhteen ei ole paljon mitä voit tehdä – bash itse ei ole tehokkain kieli ja ihmiset suosivat perliä ja pythonia nopeuden ja tehokkuuden suhteen.Voit kuitenkin nice funktion:

nice -10 resource_hungry_function 

Verrattuna kullekin kullekin koodiriville, tämä vähentää kirjoittamista paljon ja sitä voidaan käyttää kätevästi, kun haluat, että vain osa skripistä suoritetaan alhaisemmalla prioriteetilla.

Toimintojen suorittaminen taustalla auttaa minua mielestäni myös silloin, kun haluat saada kokonaiset joukko lauseita suoritettavaksi taustalla.

Joitakin esimerkkejä, joissa olen käyttänyt tätä tyyliä:

kommentit

  • En ole varma, pitäisikö sinun ottaa tämän artikkelin ehdotuksia erittäin vakavasti. Myönnetään, että sillä on muutama hyvä idea, mutta se ei selvästikään ole tottunut komentosarjojen kuorimiseen. Ei yksittäinen muuttuja missä tahansa esimerkissä on lainattu (!) ja se ehdottaa UPPER C: n käyttöä ASE-muuttujien nimet, mikä on usein erittäin huono idea, koska ne voivat olla ristiriidassa olemassa olevien env-muuttujien kanssa. Tässä vastauksessa olevilla pisteilläsi on järkevää, mutta linkitetyn artikkelin näyttää olevan kirjoittanut joku, joka on tottunut muihin kieliin ja yrittää pakottaa tyylinsä bashiin.
  • @terdon Palasin artikkeliin ja luin sen uudelleen. Ainoa paikka, jossa kirjoittaja mainitsee isojen muuttujien nimeämisen, on ” Muuttamattomissa globaaleissa muuttujissa ”. Jos pidät globaaleja muuttujia muuttujina, joiden on oltava funktion ’ ympäristössä, on järkevää tehdä niistä pääoma. Sivuhuomautuksena bash ’ s -oppaassa ei ole ’ t -tilamallia muuttujan tapauksessa. Jopa täällä hyväksytty vastaus sanoo ” yleensä ” ja ainoan ” vakio ” on Google, joka ei ’ edusta koko IT-alaa.
  • @terdon toisella huomautuksella, olen täysin samaa mieltä siitä, että muuttujan lainaus olisi pitänyt mainita artikkelissa, ja se on myös mainittu blogin kommenteissa. En myöskään ’ ei tuomitsisi tätä koodaustyyliä käyttävää henkilöä riippumatta siitä, ovatko he ’ tottuneet toiseen kieleen. Tämä koko kysymys ja vastaukset osoittavat selvästi ’ sen edut ja henkilön ’ asteen, johon ne ’ toisella kielellä tottumisella ei todennäköisesti ole merkitystä tässä.
  • @terdon hyvin, artikkeli lähetettiin osana ” lähdettä ” materiaali. Olisin voinut julkaista kaiken omina mielipiteinäni, mutta minun piti vain kiittää sitä, että osa artikkelista oppimastani asioista ja että kaikki tämä tuli tutkimuksesta ajan myötä. Kirjoittajan ’ hakusivulla näkyy, että heillä on hyvät kokemukset Linuxista ja yleensä IT: stä, joten luulen, että artikkeli ei koske ’ ei todellakaan osoita tätä, mutta luotan kokemukseesi Linux- ja shell-komentosarjojen tekemisessä, joten saatat olla oikeassa.
  • Että ’ on erinomainen vastaus, mutta haluan myös ’ lisätä, että Bashin muuttujan laajuus on funky. Tästä syystä haluan ilmoittaa muuttujat funktioiden sisällä käyttämällä local ja soittamalla kaiken main() -funktion kautta. Tämä tekee asioista paljon hallittavampia ja voit välttää mahdollisesti sotkuisen tilanteen.

Vastaa

Luettavuus on yksi asia. Mutta modularisaatiossa on muutakin kuin vain tämä. ( Semi-modularisointi on ehkä oikeampi funktioille.)

Funktioissa voit pitää joitain muuttujia paikallisena, mikä lisää luotettavuutta ja vähentää mahdollisuuksia asiat sekoittuvat.

Toinen toimintojen ammattilainen on uudelleenkäytettävyys . Kun toiminto on koodattu, sitä voidaan käyttää useita kertoja komentosarjassa. Voit myös siirtää sen toiseen komentosarjaan.

Koodisi voi nyt olla lineaarinen, mutta tulevaisuudessa voit siirtyä monisäikeinen tai moni käsittely Bash-maailmassa. Kun opit tekemään asioita toiminnoissa, sinulla on hyvät valmiudet astua rinnakkain.

Vielä yksi piste lisätä. Kuten Etsitpab Nioliv huomauttaa alla olevassa kommentissa, se on helppo ohjata toiminnoista yhtenäisenä kokonaisuutena. Mutta on vielä yksi näkökohta uudelleenohjauksille toimintojen kanssa. Uudelleenohjaukset voidaan nimittäin asettaa funktion määrittelyä pitkin. Esim .:

f () { echo something; } > log 

Funktiokutsut eivät nyt tarvitse nimenomaisia uudelleenohjauksia.

$ f 

Tämä saattaa säästää monia toistoja, mikä taas lisää luotettavuutta ja auttaa pitämään asiat järjestyksessä.

Katso myös

Kommentit

  • Erittäin hyvä vastaus, vaikka olisi paljon parempi, jos se jaetaan funktioihin.
  • Ehkä lisäämällä funktioiden avulla voit tuoda kyseisen komentosarjan toiseen komentosarjaan (käyttämällä source tai . scriptname.sh ja käytä näitä toimintoja ikään kuin ne olisivat uudessa komentosarjassa.
  • Se on jo katettu ’ toisessa vastauksessa.
  • Arvostan sitä. Mutta ’ antoisin mieluummin myös muiden ihmisten olevan tärkeitä.
  • Minulla oli tapaus tänään, kun jouduin ohjaamaan osan komentosarjan tuotoksesta tiedostoon (lähettämään sen sähköpostitse) kaiun sijasta. Minun oli yksinkertaisesti tehtävä myFunction > > myFile uudelleenohjaamaan haluttujen toimintojen ulostulo. Melko kätevä. Saattaa olla osuva.

vastaus

Mainitsin kommentissani kolme toimintojen etua:

  1. Niitä on helpompi testata ja tarkistaa oikeellisuus.

  2. Funktioita voidaan helposti käyttää (hankkia) tulevissa skripteissä

  3. Pomosi pitää niistä.

Ja älä koskaan aliarvioi luvun 3 merkitystä.

Haluan käsitellä vielä yhtä asiaa:

… joten ajon järjestyksen mielivaltainen vaihtaminen ei ole jotain, mitä yleensä teemme. Esimerkiksi, et halua yhtäkkiä haluta laittaa declare_variables walk_into_bar jälkeen, mikä rikkoa asioita.

Koodin jakamisen funktioiden hyödyntämiseksi on yritettävä tehdä toiminnoista mahdollisimman itsenäiset. Jos walk_into_bar vaatii muuttujan, joka ei käytetä muualla, niin muuttuja tulisi määritellä ja tehdä paikalliseksi kohteelle walk_into_bar. Koodin erottaminen funktioksi ja niiden välisten riippuvuuksien minimoinnin pitäisi tehdä koodista selkeämpi ja yksinkertaisempi .

Ihannetapauksessa toimintojen pitäisi olla helppo testata yksittäin. Jos vuorovaikutuksen takia niitä ei ole helppo testata, se on merkki siitä, että ne saattavat hyötyä uudelleenrakentamisesta.

Kommentit

  • I ’ d väitän, että ’ on joskus järkevää mallintaa ja pakottaa noudattamaan noita riippuvuuksia, verrattuna uudelleensuunnitteluun välttääkseen ne (koska jos sellaisia on h heistä, ja he ’ ovat riittävän karvaisia, mikä voi vain johtaa tapaukseen, jossa asioita ei enää moduloida lainkaan toimintoihin). Erittäin monimutkainen käyttötapaus inspiroi kerran kehystä tekemään juuri niin .
  • Funktioihin on jaettava, mutta esimerkki vie sen liian pitkälle. Mielestäni ainoa, joka todella vikaa minua, on muuttujailmoitustoiminto. Globaalit muuttujat, erityisesti staattiset, tulisi määritellä globaalisti tähän tarkoitukseen omistetussa kommentoidussa osiossa. Dynaamisten muuttujien tulisi olla paikallisia funktioille, jotka käyttävät ja muuttavat niitä.
  • @Xalorous Olen ’ nähnyt käytännön, jossa globaalit muuttujat alustetaan menettelyssä välivaiheena ja nopeana vaiheena ennen sellaisen menettelyn kehittämistä, joka lukee niiden arvon ulkoisesta tiedostosta … Olen samaa mieltä siitä, että määritelmän ja alustuksen erottaminen on puhtaampaa, mutta harvoin joudut taipumaan käymään läpi etunumero 3 ;-)

Vastaa

Vaikka olen täysin samaa mieltä uudelleenkäytettävyyden , luettavuuden ja herkkien suutelemisen kanssa, mutta LDP osoittaa :

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

En näe tätä kovin usein todellisessa maailmassa komentosarjojen komentosarjoja, mutta se näyttää hyvältä ajatukselta monimutkaisemmille komentosarjoille. koheesion vähentäminen auttaa välttämään virheitä, joissa huijaat muuttujaa, joka on odotettavissa koodin toisessa osassa. .

Uudelleenkäytettävyys tarkoittaa usein yhteisen funktiokirjaston luomista ja source kirjaston sisällyttämistä kaikkiin skripteihisi. Tämä ei auta heitä juoksemaan nopeammin, mutta se auttaa sinua kirjoittamaan ne nopeammin.

Kommentit

  • Harvat ihmiset käyttävät nimenomaisesti local, mutta mielestäni useimmat funktioita jaoteltuja komentosarjoja kirjoittavat ihmiset noudattavat silti suunnitteluperiaatetta. Usign local tekee virheen käyttöönoton vain vaikeammaksi. >
  • local asettaa muuttujat toimintojen ja lastensa saataville, joten ’ on todella mukavaa saada muuttuja, joka voidaan välittää alas funktiosta A, mutta ei käytettävissä toiminnosta B, joka saattaa haluta olla muuttuja samalla nimellä, mutta eri tarkoitukseen.Joten ’ on hyvä määritellä laajuus, ja kuten Voo sanoi – vähemmän virheitä

Vastaa

Rikotat koodin funktioihin samasta syystä kuin tekisit sen C / C ++, python, perl, rubiini tai mitä tahansa ohjelmointikielikoodia varten. Syvempi syy on abstraktio – kapseloit alemman tason tehtävät korkeamman tason primiteetteihin (funktioihin), jotta sinun ei tarvitse huolehtia asioiden tekemisestä. Samalla koodi muuttuu luettavammaksi (ja ylläpidettävämmäksi), ja ohjelmalogiikka selkeytyy.

Koodiani tarkastellessani minusta on kuitenkin aivan outoa, että toiminto on ilmoitettava muuttujista; tämä saa minut todella nostamaan silmäni.

Kommentit

  • Aliarvioitu vastaus IMHO. Ehdotatko sitten julistaa muuttujat funktiossa / menetelmässä main?

vastaus

Täysin erilainen syy kuin muissa vastauksissa jo annettu: yksi syy tähän tekniikkaan on joskus käytetty, jos ainoa ei-function-definition-lause ylätasolla on kutsu main, on varmistaa, että komentosarja ei vahingossa tee mitään ikävää, jos komentosarja katkaistaan. Skripti voidaan katkaista jos se on prosessin A prosessista B (kuori), ja prosessi A päättyy jostain syystä, ennen kuin se on kirjoittanut koko komentosarjan. Tämä tapahtuu erityisen todennäköisesti, jos prosessi A hakee komentosarjan etäresurssista. Turvallisuussyistä se ei ole hyvä idea, mutta se on jotain tehty, ja joitain komentosarjoja on muokattu ongelman ennakoimiseksi.

Kommentit

  • Mielenkiintoista! Mutta minusta on huolestuttavaa, että jokaisesta ohjelmasta on huolehdittava näistä asioista. Toisaalta täsmälleen tämä main() -malli on tavallinen Pythonissa, jossa tiedoston lopussa käytetään if __name__ == '__main__': main().
  • Python-idiomalla on se etu, että se antaa muiden komentosarjojen import nykyisen komentosarjan suorittamatta main. Oletan, että samanlainen vartija voitaisiin laittaa bash-käsikirjoitukseen.
  • @Jake Cobb Kyllä. Teen nyt sen kaikissa uusissa bash-skripteissä. Minulla on komentosarja, joka sisältää kaikkien uusien komentosarjojen käyttämien toimintojen perusinfrastruktuurin. Kyseinen komentosarja voidaan hankkia tai suorittaa. Jos se on peräisin, sen päätoimintoa ei suoriteta. Lähde vs. toteutus havaitaan sillä, että BASH_SOURCE sisältää suoritettavan komentosarjan nimen. Jos se ’ on sama kuin ydinkomentosarja, komentosarja suoritetaan. Muussa tapauksessa se hankitaan ’.
  • Tähän vastaukseen läheisesti liittyvä bash käyttää yksinkertaista linjapohjaista käsittelyä, kun se suoritetaan levyllä jo olevasta tiedostosta. Jos tiedosto muuttuu komentosarjan ollessa käynnissä, rivilaskuri ’ ei muutu ja se ’ jatkuu väärällä rivillä. Kapseloimalla kaikki toimintoihin varmistetaan, että ’ ladataan kaikki muistiin ennen kuin suoritat mitään, joten tiedoston muuttaminen ei vaikuta siihen. Id = ”9b8d4d3bb1”>

li>

vastaus

Joitakin asiaankuuluvia truismeja ohjelmoinnista:

Kommentit alkavat pysäytysvälinä, koska niitä ei ole. osaa ilmaista ajatuksesi selkeästi koodina * ja muuttua huonommaksi (tai yksinkertaisesti vääräksi). Siksi, mikäli mahdollista, ilmaise käsitteitä, rakenteita, päättelyjä, semantiikkaa, kulkua, virheenkäsittelyä ja muuta asiaa, joka liittyy koodin ymmärtämiseen koodina.

Se sanoi, Bash-funktioissa on joitain ongelmia, joita ei löydy useimmilla kielillä:

  • Bash-nimien väli on kauheaa. Esimerkiksi avainsanan local käytön unohtaminen johtaa maailmanlaajuisen nimitilan saastuttamiseen.
  • local foo="$(bar)" -toiminnon käyttäminen johtaa menettää bar poistumiskoodin.
  • Ei ole nimettyjä parametreja, joten sinun on pidettävä mielessä, mitä "$@" tarkoittaa eri tilanteissa.

* Olen pahoillani, jos tämä loukkaa, mutta sen jälkeen Kommenttien käyttö muutaman vuoden ajan ja kehittäminen ilman niitä ** vuosien ajan on melko selvää, mikä on parempaa.

** Kommenttien käyttäminen lisensointiin, API-dokumentaatioon ja vastaaviin on silti välttämätöntä.

Kommentit

  • Asetin melkein kaikki paikalliset muuttujat julistamalla ne nolliksi funktion alkuun …local foo="" Määritä ne sitten komennon suorittamisen avulla vaikuttamaan tulokseen … foo="$(bar)" || { echo "bar() failed"; return 1; }. Tämä vie meidät pois toiminnosta nopeasti, kun vaadittua arvoa ei voida asettaa. Kiharat ovat välttämättömiä sen varmistamiseksi, että return 1 suoritetaan vain epäonnistumisen vuoksi.
  • Halusin vain kommentoida luettelomerkkejäsi. Jos käytät ’ -subhell-funktioita ’ (sulkeilla erotetut toiminnot eivät sulkeisia sulkeita), 1) don ’ ei tarvitse käyttää paikallista, mutta saada paikallisen edut, 2) Don ’ ei tule törmätä komentojen korvaamisen poistumiskoodin menettämiseen ryhmässä local foo=$(bar) niin paljon (koska ’ et käytä paikallista) 3) Älä ’ ei tarvitse huolehtia vahingossa saastuttamisesta tai globaalin laajuuden muuttamisesta 4) pystyvät välittämään ’ nimetyt parametrit ’, jotka ovat ’ paikallinen ’ toimintoosi käyttämällä syntaksia foo=bar baz=buz my-command

Vastaa

Prosessi vaatii jakson. Useimmat tehtävät ovat peräkkäisiä. Tilauksen kanssa ei ole mitään järkeä sekaantua.

Mutta ohjelmoinnin erittäin suuri asia – joka sisältää komentosarjat – on testaus. Testaus, testaus, testaus. Mitä testiskriptejä sinulla on tällä hetkellä skriptien oikeellisuuden varmistamiseksi?

Pomo yrittää ohjata sinua olemaan komentosarjan poika ohjelmoijaksi. Tämä on hyvä suunta sisäänpäin. Ihmiset, jotka tulevat sinun jälkeesi, pitävät sinusta.

MUTTA. Muista aina prosessisuuntautuneet juuresi. Jos on järkevää järjestää toiminnot siinä järjestyksessä, jossa ne tyypillisesti suoritetaan, tee se, ainakin ensimmäisenä kierroksena.

Myöhemmin huomaat, että jotkut toiminnot ovat syötteen käsittely, toisten tuotos, toisten käsittely, toiset mallinnus ja muut tietojen käsittely, joten voi olla järkevää ryhmitellä samanlaisia menetelmiä, ehkä jopa siirtää ne erillisiin tiedostoihin.

Myöhemmin voit ehkä huomaa, että olet nyt kirjoittanut kirjastoja pienistä auttajatoiminnoista, joita käytät monissa komentosarjoissasi.

Vastaa

Kommentit ja väli ei pääse mihinkään toimintojen luettavuuteen, kuten osoitan. Ilman toimintoja et voi nähdä metsää puiden varalta – suuret ongelmat piiloutuvat monien yksityiskohtien kesken. Toisin sanoen ihmiset eivät voi keskittyä samanaikaisesti hienoihin yksityiskohtiin ja kokonaisuuteen. Se ei välttämättä ole ilmeistä lyhyessä käsikirjoituksessa; niin kauan kuin se on lyhyt, se voi olla tarpeeksi luettavissa. Ohjelmisto kuitenkin kasvaa, ei pienempi , ja varmasti se on osa yrityksesi koko ohjelmistojärjestelmää, joka on varmasti paljon suurempi, todennäköisesti miljoonia rivejä.

Harkitse, antaisinko sinulle tällaisia ohjeita:

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) 

Mennessäsi puoliväliin tai jopa 5 prosenttiin, olisit unohtanut, mitä ensimmäiset vaiheet olivat. Et voinut havaita suurinta osaa ongelmista, koska et voinut nähdä metsää puiden varalta. Vertaa toimintoihin:

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

Se on varmasti paljon ymmärrettävämpi, riippumatta siitä kuinka monta kommenttia voisit laittaa rivi riviltä peräkkäiseen versioon. Se tekee myös paljon todennäköisemmäksi, että huomaat, että olet unohtanut tehdä kahvin ja todennäköisesti unohdin sit_down () lopussa. Kun mielesi ajattelee grep- ja awk-regexien yksityiskohtia, et voi ajatella suurta kuvaa – ”entä jos kahvia ei ole tehty”?

Toiminnot antavat sinun nähdä ensisijaisesti kokonaiskuvan, ja huomaa, että unohdit valmistaa kahvia (tai että joku saattaa mieluummin valmistaa teetä). Toisinaan, eri mieltä, olet huolissasi yksityiskohtaisesta toteutuksesta.

On myös muita etuja, joista on keskusteltu Muita etuja, joita ei selkeästi mainita muissa vastauksissa, on se, että toiminnot takaavat tärkeän virheen estämisen ja korjaamisen. Jos huomaat, että joku muuttuja $ foo oikeassa funktiossa walk_to () oli väärä, tiedät, että sinun on vain tarkasteltava kyseisen toiminnon 6 muuta riviä löytääksesi kaiken, mihin ongelma voi vaikuttaa, ja kaiken, mikä voisi ovat aiheuttaneet sen olevan väärä. Ilman (oikeita) toimintoja kaikki ja kaikki koko järjestelmässä voivat olla syynä siihen, että $ foo on virheellinen, ja $ foo voi vaikuttaa mihin tahansa ja kaikkeen. Siksi et voi korjata $ foo: ta turvallisesti tutkimatta ohjelman kaikkia yksittäisiä rivejä. Jos $ foo on paikallinen toiminnolle, voit taata, että muutokset ovat turvallisia ja oikeita tarkistamalla vain kyseisen toiminnon.

Kommentit

  • Tämä ei ole ’ t bash syntaksia.’ on kuitenkin häpeä; En usko, että ’ uskoo, että on mahdollista siirtää syöttö tällaisille toiminnoille. (ts. pour(); < coffee). Se näyttää enemmän c++ tai php (mielestäni).
  • @ tjt263 ilman sulkeita, se ’ bash-syntaksi: kaada kahvia. Parenssien kanssa se ’ on melkein jokainen muu kieli. 🙂

Vastaa

Aika on rahaa

On olemassa muita hyviä vastauksia , jotka levittävät teknisiä syitä kirjoittaa modulaarisesti komentosarja, mahdollisesti pitkä, kehitetty työympäristössä, kehitetty käytettäväksi ryhmä ihmisiä eikä vain omaan käyttöön.

Haluan keskity yhteen odotukseen: työympäristössä ”aika on rahaa” . Joten virheiden puuttuminen ja koodisi suorituskyky arvioidaan yhdessä luettavuuden , testattavuuden, ylläpidettävyyden, palautettavuuden, uudelleenkäyttö

Kirjoittaminen ” moduulit ” koodi lyhentää lukuaikaa, joka tarvitaan paitsi itse kooderin myös testaajien tai testaajien käyttämään aikaan pomo. Huomaa lisäksi, että pomon aika maksetaan yleensä enemmän kuin kooderin aika ja että pomosi arvioi työsi laadun.

Lisäksi kirjoita itsenäiset ”moduulit” koodi (jopa bash-komentosarja) antaa sinun työskennellä ”rinnakkain” tiimisi muu komponentti lyhentää kokonaistuotantoaikaa ja käyttää parhaimmillaan yhden asiantuntijaa, tarkistaa tai kirjoittaa osa ilman sivuvaikutuksia muihin, kierrättää juuri kirjoittamasi koodi ”sellaisenaan” toiselle ohjelmalle / komentosarjalle, kirjastojen (tai katkelmakirjastojen) luomiseksi, kokonaiskoon ja siihen liittyvän virheiden todennäköisyyden pienentämiseksi, jokaisen osan virheenkorjaamiseksi ja testaamiseksi … osioi ohjelma / komentosarja ja lisää sen luettavuutta. Kaikki asiat, jotka säästävät aikaa ja rahaa. Haittapuoli on, että sinun on noudatettava standardeja ja kommentoitava toimintojasi (jotka sinulla on tehtävä työympäristössä).

-standardin noudattaminen hidastaa työsi alussa, mutta se nopeuttaa kaikkien muiden (ja myös sinun) työtä jälkikäteen. Todellakin, kun yhteistyön määrä kasvaa mukana olevien ihmisten määrässä, siitä tulee väistämätön tarve. Joten vaikka uskonkin, että globaalit muuttujat on määriteltävä globaalisti eikä funktiossa, voin ymmärtää standardin, joka initsialisoi ne funktiossa nimeltä declare_variables() kutsutaan aina main() yhden ensimmäisellä rivillä …

Viimeisenä mutta ei vähäisimpänä, älä aliarvioi modernin lähdekoodin mahdollisuutta toimittajat näyttämään tai piilottamaan valikoivasti erilliset rutiinit ( Koodin taitto ). Tämä pitää koodin pakattuna ja keskittää käyttäjän säästämään aikaa uudelleen.

kirjoita kuvan kuvaus tähän

Täältä näet miten avautuu vain walk_into_bar() -toiminto. Jopa muiden rivien pituus oli 1000 riviä, voit silti pitää kaiken koodin hallinnassa yhdellä sivulla. Huomaa, että se on taitettu jopa osioon, jossa ilmoitat / alustat muuttujat.

Vastaa

Toinen syy se jätetään usein huomiotta, on bash: n syntaksin jäsentäminen:

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

Tämä komentosarja sisältää ilmeisesti syntaksivirheen, eikä bashin pitäisi suorittaa sitä ollenkaan, eikö? Väärä.

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

Jos käärimme koodin funktioon, sitä ei tapahdu:

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 

vastaus

Muissa vastauksissa annettujen syiden lisäksi:

  1. Psykologia: Ohjelmoijalla, jonka tuottavuutta mitataan koodiriveillä, on kannustin kirjoittaa tarpeettomasti yksityiskohtaista koodia. Mitä enemmän hallintaa on Kun keskitytään koodiriveihin, sitä enemmän kannustimia ohjelmoijan on laajennettava koodiaan tarpeettoman monimutkaisella tavalla.

kommentit

  • Se ei ole niin huono vastaus, kuten alasäänestykset sanovat. Huomaa: agc sanoo, myös tämä on mahdollisuus, ja kyllä, se on. Hän ei ’ ei sano, että se olisi ainoa mahdollisuus, ja ei ’ syytä ketään, kertoo vain tosiasiat. Vaikka mielestäni tänään on melkein tuntematon suora ” koodirivi ” – > ” $$ ” -tyyppinen urakkatyö, epäsuoralla tavalla on melko yleistä, että kyllä, johtajat laskevat tuotetun koodin massan / pomot.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *