Perché scrivere un intero script bash in funzioni?


59

Al lavoro, scrivo spesso script di bash. Il mio supervisore ha suggerito che l'intero script sia suddiviso in funzioni, simile al seguente esempio:

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

C'è qualche motivo per farlo oltre alla "leggibilità", che penso possa essere ugualmente ben stabilita con qualche commento in più e qualche interlinea?

Rende l'esecuzione dello script più efficiente (in realtà mi aspetterei il contrario, se non altro) o semplifica la modifica del codice oltre il suddetto potenziale di leggibilità? O è davvero solo una preferenza stilistica?

Si noti che sebbene lo script non lo dimostri bene, l '"ordine di esecuzione" delle funzioni nei nostri script effettivi tende ad essere molto lineare - walk_into_bardipende dalle cose che i_am_fooha fatto e do_bazagisce sulle cose impostate da walk_into_bar- così essendo in grado di scambiare arbitrariamente l'ordine di esecuzione non è qualcosa che faremmo generalmente. Per esempio, non si improvvisamente voglia di mettere declare_variablesdopo walk_into_bar, che rompere le cose.

Un esempio di come scriverei lo script sopra sarebbe:

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

30
Mi piace il tuo capo. Nei miei script ho anche messo main()in alto e aggiungo main "$@"in fondo per chiamarlo. Ciò ti consente di vedere la logica dello script di alto livello per prima cosa quando la apri.
John Kugelman supporta Monica il

22
Non sono d'accordo con l'idea che la leggibilità possa "essere ugualmente ben stabilita con qualche commento in più e un po 'di spazio." Tranne forse per la fiction, non vorrei occuparmi di un libro che non ha un sommario e nomi descrittivi per ogni capitolo e sezione. Nei linguaggi di programmazione, questo è il tipo di leggibilità che le funzioni possono fornire e i commenti non possono.
Rhymoid,

6
Nota che le variabili dichiarate nelle funzioni dovrebbero essere dichiarate local- questo fornisce un ambito variabile che è incredibilmente importante in qualsiasi script non banale.
Boris the Spider,

8
Non sono d'accordo con il tuo capo. Se devi suddividere lo script in funzioni, probabilmente non dovresti scrivere uno script di shell in primo luogo. Scrivi invece un programma.
el.pescado,

6
Le funzioni sono per i processi che si ripetono, all'interno dello script o in più di uno script. Consentono inoltre di mettere a punto metodologie uniformi. Ad esempio utilizzando una funzione per scrivere su syslog. Finché tutti usano la stessa funzione, le voci del syslog sono più coerenti. Funzioni monouso come il tuo esempio complicano inutilmente lo script. In alcuni casi, introducono problemi (scoping variabile).
Xalorous,

Risposte:


40

Ho iniziato a usare lo stesso stile di programmazione bash dopo aver letto il post sul blog di Kfir Lavi "Defensive Bash Programming" . Dà alcuni buoni motivi, ma personalmente trovo questi i più importanti:

  • le procedure diventano descrittive: è molto più facile capire cosa dovrebbe fare una parte particolare del codice. Invece di wall of code, vedi "Oh, la find_log_errorsfunzione legge quel file di registro per errori". Confrontalo con la ricerca di un sacco di righe awk / grep / sed che usano god sa quale tipo di regex nel mezzo di un lungo script - non hai idea di cosa ci faccia a meno che non ci siano commenti.

  • è possibile eseguire il debug delle funzioni racchiudendo in set -xe set +x. Una volta che sai che il resto del codice funziona bene, puoi usare questo trucco per concentrarti solo sul debug di quella specifica funzione. Certo, puoi racchiudere parti della sceneggiatura, ma se fosse una porzione lunga? È più facile fare qualcosa del genere:

     set -x
     parse_process_list
     set +x
  • utilizzo della stampa con cat <<- EOF . . . EOF. L'ho usato parecchie volte per rendere il mio codice molto più professionale. Inoltre, parse_args()con la getoptsfunzione è abbastanza conveniente. Ancora una volta, questo aiuta con la leggibilità, invece di inserire tutto nella sceneggiatura come un gigantesco muro di testo. È anche conveniente riutilizzarli.

E ovviamente, questo è molto più leggibile per qualcuno che conosce C o Java, o Vala, ma ha un'esperienza bash limitata. Per quanto riguarda l'efficienza, non c'è molto che puoi fare: bash stesso non è il linguaggio più efficiente e le persone preferiscono il perl e il pitone quando si tratta di velocità ed efficienza. Tuttavia, è possibile niceuna funzione:

nice -10 resource_hungry_function

Rispetto a chiamare nice su ogni singola riga di codice, ciò riduce un sacco di digitazione E può essere comodamente utilizzato quando si desidera che solo una parte dello script venga eseguita con priorità inferiore.

L'esecuzione di funzioni in background, a mio avviso, aiuta anche quando vuoi avere un sacco di istruzioni da eseguire in background.

Alcuni degli esempi in cui ho usato questo stile:


3
Non sono sicuro che dovresti prendere molto seriamente eventuali suggerimenti da quell'articolo. Certo, ha alcune buone idee, ma chiaramente non è qualcuno abituato a shell scripting. Non viene citata una sola variabile in nessuno degli esempi (!) E suggerisce l'utilizzo di nomi di variabili UPPER CASE, che è spesso una pessima idea poiché possono entrare in conflitto con gli ambienti esistenti. I tuoi punti in questa risposta hanno senso, ma l'articolo collegato sembra essere stato scritto da qualcuno che è appena abituato ad altre lingue e sta cercando di forzare il loro stile su bash.
terdon

1
@terdon Sono tornato all'articolo e l'ho riletto. L'unico posto in cui l'autore menziona la denominazione delle variabili maiuscole è in "Variabili globali immutabili". Se consideri le variabili globali come quelle che devono essere all'interno dell'ambiente della funzione, allora ha senso renderle capitale. Sulla nota a margine, il manuale di bash non indica la convenzione per il caso variabile. Anche qui la risposta accettata dice "di solito" e l'unico "standard" è di Google, che non rappresenta l'intero settore IT.
Sergiy Kolodyazhnyy,

@terdon su un'altra nota, sono d'accordo al 100% sul fatto che la quotazione variabile avrebbe dovuto essere menzionata nell'articolo, ed è stato sottolineato anche nei commenti sul blog. Inoltre, non giudicherei qualcuno che usa questo stile di codifica, indipendentemente dal fatto che siano abituati o meno a un'altra lingua. Tutta questa domanda e le risposte mostrano chiaramente che ci sono vantaggi, e il grado di persona a cui sono abituati in un'altra lingua è probabilmente irrilevante qui.
Sergiy Kolodyazhnyy,

1
@terdon bene, l'articolo è stato pubblicato come parte del materiale "sorgente". Avrei potuto pubblicare tutto come le mie opinioni, ma dovevo solo dare credito al fatto che alcune delle cose che avevo imparato dall'articolo e che tutto questo venisse dalla ricerca nel tempo. La pagina del linkedin dell'autore mostra che hanno una buona esperienza con Linux e IT in generale, quindi immagino che l'articolo non lo mostri davvero, ma mi fido della tua esperienza quando si tratta di Linux e script di shell, quindi potresti avere ragione .
Sergiy Kolodyazhnyy,

1
Questa è una risposta eccellente, ma vorrei anche aggiungere che l'ambito variabile in Bash è funky. Per questo motivo, preferisco dichiarare le mie variabili all'interno delle funzioni usando locale chiamando tutto tramite la main()funzione. Questo rende le cose molto più gestibili e puoi evitare una situazione potenzialmente disordinata.
Housni,

65

La leggibilità è una cosa. Ma c'è di più nella modularizzazione oltre a questo. (La semi-modularizzazione è forse più corretta per le funzioni.)

Nelle funzioni è possibile mantenere alcune variabili locali, il che aumenta l' affidabilità , diminuendo la possibilità che si verifichino errori.

Un altro pro di funzioni è la riutilizzabilità . Una volta codificata, una funzione può essere applicata più volte nello script. Puoi anche portarlo su un altro script.

Il tuo codice ora potrebbe essere lineare, ma in futuro potresti entrare nel regno del multi-threading o del multi-processing nel mondo Bash. Una volta che imparerai a fare le cose con le funzioni, sarai ben equipaggiato per entrare nel parallelo.

Un altro punto da aggiungere. Come osserva Etsitpab Nioliv nel commento qui sotto, è facile reindirizzare dalle funzioni come entità coerente. Ma c'è un altro aspetto dei reindirizzamenti con funzioni. Vale a dire, i reindirizzamenti possono essere impostati lungo la definizione della funzione. Per esempio.:

f () { echo something; } > log

Ora non sono necessari reindirizzamenti espliciti dalle chiamate di funzione.

$ f

Questo può risparmiare molte ripetizioni, il che aumenta di nuovo l'affidabilità e aiuta a mantenere le cose in ordine.

Guarda anche


55
Ottima risposta, anche se sarebbe molto meglio se fosse suddiviso in funzioni.
Pierre Arlaud,

1
Forse aggiungi che le funzioni ti consentono di importare quello script in un altro script (usando sourceo . scriptname.sh, e usare quelle funzioni come se fossero nel tuo nuovo script.
SnakeDoc

Questo è già trattato in un'altra risposta.
Tomasz,

1
Lo apprezzo. Ma preferirei che anche le altre persone fossero importanti.
Tomasz,

7
Oggi ho dovuto affrontare un caso in cui dovevo reindirizzare parte dell'output di uno script su un file (per inviarlo via e-mail) invece di fare eco. Ho semplicemente dovuto fare myFunction >> myFile per reindirizzare l'output delle funzioni desiderate. Abbastanza conveniente. Potrebbe essere pertinente.
Etsitpab Nioliv,

39

Nel mio commento, ho citato tre vantaggi delle funzioni:

  1. Sono più facili da testare e verificare la correttezza.

  2. Le funzioni possono essere facilmente riutilizzate (provenienti) in script futuri

  3. Al tuo capo piacciono.

E non sottovalutare mai l'importanza del numero 3.

Vorrei affrontare un altro problema:

... quindi essere in grado di scambiare arbitrariamente l'ordine di esecuzione non è qualcosa che faremmo generalmente. Per esempio, non si improvvisamente voglia di mettere declare_variablesdopo walk_into_bar, che rompere le cose.

Per ottenere il vantaggio di suddividere il codice in funzioni, si dovrebbe cercare di rendere le funzioni il più indipendenti possibile. Se walk_into_barrichiede una variabile che non viene utilizzata altrove, tale variabile deve essere definita e resa locale walk_into_bar. Il processo di separazione del codice in funzioni e di riduzione al minimo delle loro interdipendenze dovrebbe rendere il codice più chiaro e semplice.

Idealmente, le funzioni dovrebbero essere facili da testare individualmente. Se, a causa delle interazioni, non sono facili da testare, allora questo è un segno che potrebbero beneficiare del refactoring.


Direi che a volte è sensato modellare e far valere tali dipendenze, rispetto al refactoring per evitarle (dal momento che se ce ne sono abbastanza, e sono sufficientemente pelose, ciò può portare a un caso in cui le cose non sono più modularizzate in funzioni a tutti). Un caso d'uso molto complicato ha ispirato una volta un framework per fare proprio questo .
Charles Duffy,

4
Ciò che deve essere diviso in funzioni dovrebbe essere, ma l'esempio lo porta troppo lontano. Penso che l'unico che mi stia davvero dando fastidio sia la funzione di dichiarazione variabile. Le variabili globali, in particolare quelle statiche, dovrebbero essere definite a livello globale in una sezione commentata dedicata a tale scopo. Le variabili dinamiche dovrebbero essere locali alle funzioni che le usano e le modificano.
Xalorous,

@Xalorous Ho visto una pratica in cui le variabili globali sono inizializzate in una procedura, come un passo intermedio e veloce prima dello sviluppo di una procedura che legge il loro valore da un file esterno ... Sono d'accordo che dovrebbe essere più pulito separare la definizione e inizializzazione ma raramente devi piegarti per subire il vantaggio numero 3;-)
Hastur

14

Rompi il codice in funzioni per lo stesso motivo per cui lo faresti per C / C ++, python, perl, ruby ​​o qualunque altro codice del linguaggio di programmazione. La ragione più profonda è l'astrazione: incapsuli le attività di livello inferiore in primitive (funzioni) di livello superiore in modo da non doverti preoccupare di come vengono fatte le cose. Allo stesso tempo, il codice diventa più leggibile (e gestibile) e la logica del programma diventa più chiara.

Tuttavia, guardando il tuo codice, trovo abbastanza strano avere una funzione per dichiarare le variabili; questo mi fa davvero alzare un sopracciglio.


Risposta sottovalutata IMHO. mainQuindi suggerisci di dichiarare le variabili nella funzione / metodo?
David Tabernero M.,

13

Mentre sono totalmente d'accordo con la riusabilità , la leggibilità e il bacio delicato dei capi, ma c'è un altro vantaggio delle funzioni in : portata variabile . Come mostra 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.

Non lo vedo molto spesso negli script di shell del mondo reale, ma sembra una buona idea per script più complessi. Ridurre la coesione aiuta a evitare bug nei casi in cui stai bloccando una variabile prevista in un'altra parte del codice.

Riusabilità spesso significa creare una libreria comune di funzioni e sourceinserire quella libreria in tutti i tuoi script. Questo non li aiuterà a correre più velocemente, ma ti aiuterà a scriverli più velocemente.


1
Poche persone usano esplicitamente local, ma penso che la maggior parte delle persone che scrivono script suddivisi in funzioni seguano ancora il principio del design. Usign localrende più difficile l'introduzione di bug.
Voo

localrende le variabili disponibili per la funzione e i suoi figli, quindi è davvero bello avere una variabile che può essere tramandata dalla funzione A, ma non disponibile per la funzione B, che potrebbe voler avere una variabile con lo stesso nome ma con scopi diversi. Quindi va bene per definire l'ambito e, come ha detto Voo - meno bug
Sergiy Kolodyazhnyy

10

Un motivo completamente diverso da quelli già indicati in altre risposte: uno dei motivi per cui questa tecnica viene talvolta utilizzata, in cui l'unica affermazione di non funzione al primo livello è una chiamata a main, è assicurarsi che lo script non faccia accidentalmente nulla di brutto se lo script viene troncato. Lo script può essere troncato se viene reindirizzato dal processo A al processo B (shell) e il processo A termina per qualsiasi motivo prima di aver finito di scrivere l'intero script. Ciò è particolarmente probabile che accada se il processo A recupera lo script da una risorsa remota. Mentre per motivi di sicurezza non è una buona idea, è qualcosa che viene fatto e alcuni script sono stati modificati per anticipare il problema.


5
Interessante! Ma trovo preoccupante che uno debba prendersi cura di quelle cose in ciascuno dei programmi. D'altra parte, esattamente questo main()schema è usuale in Python dove si usa if __name__ == '__main__': main()alla fine del file.
Martin Ueding,

1
Il linguaggio di Python ha il vantaggio di lasciare ad altri script importlo script corrente senza eseguirlo main. Suppongo che una guardia simile potrebbe essere messa in uno script bash.
Jake Cobb,

@Jake Cobb Sì. Ora lo faccio in tutti i nuovi script bash. Ho uno script che contiene un'infrastruttura di base delle funzioni utilizzate da tutti i nuovi script. Lo script può essere fornito o eseguito. Se proveniente, la sua funzione principale non viene eseguita. Il rilevamento dell'origine rispetto all'esecuzione è dovuto al fatto che BASH_SOURCE contiene il nome dello script in esecuzione. Se è uguale allo script principale, lo script viene eseguito. Altrimenti, viene fornito.
DocSalvager,

7

Un processo richiede una sequenza. La maggior parte delle attività sono sequenziali. Non ha senso confondere l'ordine.

Ma la cosa grandiosa della programmazione - che include gli script - è il testing. Test, test, test. Quali script di test hai attualmente per convalidare la correttezza dei tuoi script?

Il tuo capo sta cercando di guidarti dall'essere uno script per bambini a un programmatore. Questa è una buona direzione per entrare. Alle persone che vengono dopo di te piacerai.

MA. Ricorda sempre le tue radici orientate al processo. Se ha senso disporre delle funzioni ordinate nella sequenza in cui sono in genere eseguite, allora fallo almeno come primo passaggio.

Successivamente, vedrai che alcune delle tue funzioni gestiscono l'input, altre l'output, altre l'elaborazione, altre la modellazione dei dati e altre la manipolazione dei dati, quindi potrebbe essere intelligente raggruppare metodi simili, magari spostandoli in file separati .

Più tardi, potresti arrivare a capire che ora hai scritto librerie di piccole funzioni di supporto che usi in molti dei tuoi script.


7

Commenti e spaziatura non possono avvicinarsi in alcun modo alla leggibilità che le funzioni possono fare, come dimostrerò. Senza funzioni, non puoi vedere la foresta per gli alberi - grandi problemi si nascondono tra molte linee di dettaglio. In altre parole, le persone non possono contemporaneamente concentrarsi sui dettagli fini e sul quadro generale. Ciò potrebbe non essere ovvio in una breve sceneggiatura; fintanto che rimane breve può essere abbastanza leggibile. Il software diventa più grande, tuttavia, non più piccolo, e certamente fa parte dell'intero sistema software della tua azienda, che è sicuramente molto più grande, probabilmente milioni di linee.

Considera se ti ho dato istruzioni come questa:

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)

Prima di arrivare a metà, o addirittura del 5%, avresti dimenticato quali erano i primi passi. Non è possibile individuare la maggior parte dei problemi, perché non è possibile vedere la foresta per gli alberi. Confronta con le funzioni:

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

Questo è sicuramente molto più comprensibile, indipendentemente da quanti commenti potresti inserire nella versione sequenziale riga per riga. Inoltre rende molto più probabile che noterai che ti sei dimenticato di preparare il caffè, e probabilmente hai dimenticato sit_down () alla fine. Quando la tua mente sta pensando ai dettagli di grep e awk regexes, non puoi pensare a un quadro generale: "e se non ci fosse il caffè fatto?

Le funzioni consentono principalmente di vedere il quadro generale e notare che hai dimenticato di preparare il caffè (o che qualcuno potrebbe preferire il tè). In un altro momento, in un diverso stato d'animo, ti preoccupi per l'implementazione dettagliata.

Ci sono anche altri vantaggi discussi in altre risposte, ovviamente. Un altro vantaggio non chiaramente indicato nelle altre risposte è che le funzioni forniscono una garanzia importante per prevenire e correggere i bug. Se scopri che qualche variabile $ foo nella funzione corretta walk_to () era sbagliata, sai che devi solo guardare le altre 6 righe di quella funzione per trovare tutto ciò che potrebbe essere stato interessato da quel problema e tutto ciò che potrebbe hanno causato che fosse sbagliato. Senza funzioni (appropriate), qualsiasi cosa nell'intero sistema potrebbe essere causa di errori di $ foo e qualsiasi cosa potrebbe essere influenzata da $ foo. Pertanto non è possibile correggere $ foo in modo sicuro senza riesaminare ogni singola riga del programma. Se $ foo è locale in una funzione,


1
Questa non è bashsintassi. È un peccato però; Non penso che ci sia un modo per trasmettere input a funzioni del genere. (cioè pour();< coffee). Sembra più c++o php(penso).
voci

2
@ tjt263 senza parentesi, è sintassi bash: versare il caffè. Con le parentesi, è praticamente ogni altra lingua. :)
Ray Morris,

6

Alcuni truismi rilevanti sulla programmazione:

  • Il tuo programma cambierà, anche se il tuo capo insiste che non è così.
  • Solo il codice e l'input influiscono sul comportamento del programma.
  • La denominazione è difficile.

I commenti iniziano come un gap-gap per non essere in grado di esprimere chiaramente le tue idee nel codice * e peggiorare (o semplicemente sbagliare) con il cambiamento. Pertanto, se possibile, esprimete concetti, strutture, ragionamento, semantica, flusso, gestione degli errori e qualsiasi altra cosa pertinente alla comprensione del codice come codice.

Detto questo, le funzioni di Bash hanno alcuni problemi che non si trovano nella maggior parte delle lingue:

  • Il namespace è terribile in Bash. Ad esempio, dimenticare di utilizzare la localparola chiave provoca l'inquinamento dello spazio dei nomi globale.
  • L'uso di local foo="$(bar)"risultati comporta la perdita del codice di uscita dibar .
  • Non ci sono parametri nominati, quindi devi tenere presente cosa "$@"significa in contesti diversi.

* Mi dispiace se questo offende, ma dopo aver usato i commenti per alcuni anni e aver sviluppato senza di loro ** per altri anni è abbastanza chiaro quale è superiore.

** È ancora necessario utilizzare i commenti per le licenze, la documentazione API e simili.


Ho impostato quasi tutte le variabili locali dichiarandoli nulli all'inizio della funzione ... local foo=""Poi l'impostazione utilizzando l'esecuzione di comandi per agire sul risultato ... foo="$(bar)" || { echo "bar() failed"; return 1; }. Questo ci fa uscire rapidamente dalla funzione quando non è possibile impostare un valore richiesto. Le parentesi graffe sono necessarie per assicurare che return 1venga eseguita solo in caso di fallimento.
DocSalvager

6

Il tempo è denaro

Ci sono altre buone risposte che fanno luce sui motivi tecnici per scrivere in modo modulare una sceneggiatura, potenzialmente lunga, sviluppata in un ambiente di lavoro, sviluppata per essere utilizzata da un gruppo di persone e non solo per uso personale.

Voglio concentrarmi su un aspetto: in un ambiente di lavoro "il tempo è denaro" . Quindi l'assenza di bug e le prestazioni del tuo codice vengono valutate insieme a leggibilità , testabilità, manutenibilità , rifattabilità, riusabilità ...

Scrivendo in "moduli" un codice diminuirà il tempo di lettura necessaria non solo dal coder in sé, ma anche il tempo impiegato dai tester o dal boss. Inoltre, nota che il tempo di un capo viene generalmente pagato più del tempo di un programmatore e che il tuo capo valuterà la qualità del tuo lavoro.

Inoltre scrivere in "moduli" indipendenti un codice (anche uno script bash) ti consentirà di lavorare in "parallelo" con altri componenti del tuo team abbreviando i tempi complessivi di produzione e usando al meglio l'esperienza del singolo, per rivedere o riscrivere una parte con nessun effetto collaterale sugli altri, per riciclare il codice che hai appena scritto "così com'è"per un altro programma / script, per creare librerie (o librerie di snippet), per ridurre le dimensioni complessive e la relativa probabilità di errori, eseguire il debug e testare accuratamente ogni singola parte ... e ovviamente organizzerà nella sezione logica il tuo programma / script e migliorarne la leggibilità. Tutto ciò che farà risparmiare tempo e denaro. Lo svantaggio è che devi attenersi agli standard e commentare le tue funzioni (che devi comunque fare in un ambiente di lavoro).

Aderire a uno standard rallenterà il tuo lavoro all'inizio, ma accelererà il lavoro di tutti gli altri (e anche dei tuoi) in seguito. In effetti, quando la collaborazione cresce nel numero di persone coinvolte, questo diventa un bisogno inevitabile. Quindi, per esempio, anche se credo che le variabili globali debbano essere definite a livello globale e non in una funzione, posso capire uno standard che le inizializza in una funzione declare_variables()chiamata sempre chiamata nella prima riga di main()quella ...

Ultimo ma non meno importante, non sottovalutare la possibilità nei moderni editor di codice sorgente di mostrare o nascondere routine selettivamente separate ( piegatura del codice ). Ciò manterrà compatto il codice e focalizzato l'utente risparmiando ancora tempo.

inserisci qui la descrizione dell'immagine

Qui sopra puoi vedere come si svolge solo la walk_into_bar()funzione. Anche degli altri erano lunghi 1000 righe ciascuno, si poteva comunque tenere sotto controllo tutto il codice in una singola pagina. Nota che è piegata anche la sezione in cui vai a dichiarare / inizializzare le variabili.


2

A parte le ragioni fornite in altre risposte:

  1. Psicologia: un programmatore la cui produttività viene misurata in righe di codice avrà un incentivo a scrivere codice inutilmente dettagliato. Più la gestione si concentra su linee di codice, maggiore è l'incentivo che il programmatore deve espandere il proprio codice con complessità non necessaria. Ciò è indesiderabile poiché una maggiore complessità può comportare un aumento dei costi di manutenzione e un maggiore sforzo richiesto per la correzione degli errori.

1
Non è una risposta così negativa, come dicono i voti negativi. Nota: agc dice, anche questa è una possibilità, e sì, lo è. Non dice che sarebbe l'unica possibilità, e non accusa nessuno, afferma solo i fatti. Anche se penso che oggi sia quasi inaudito un lavoro diretto in stile "code line" -> "$$", su mezzi indiretti è abbastanza comune, che sì, la massa del codice prodotto conta dai leader / capi.
user259412

2

Un altro motivo che viene spesso trascurato è l'analisi della sintassi di bash:

set -eu

echo "this shouldn't run"
{
echo "this shouldn't run either"

Questo script ovviamente contiene un errore di sintassi e bash non dovrebbe eseguirlo affatto, giusto? Sbagliato.

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

Se avessimo racchiuso il codice in una funzione, ciò non accadrebbe:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.