Inoltrare dichiarazioni di funzioni in uno script Bash o Shell?


96

C'è una cosa del genere basho almeno qualcosa di simile (aggiramento) come le dichiarazioni anticipate, ben note in C / C ++, per esempio?

O esiste una cosa del genere perché ad esempio viene sempre eseguita in un passaggio (riga dopo riga)?

Se non ci sono dichiarazioni anticipate, cosa devo fare per rendere il mio script più facile da leggere. È piuttosto lungo e queste definizioni di funzioni all'inizio, mescolate con variabili globali, fanno sembrare il mio script brutto e difficile da leggere / capire)? Chiedo di apprendere alcune pratiche ben note / migliori per questi casi.


Per esempio:

# something like forward declaration
function func

# execution of the function
func

# definition of func
function func
{
    echo 123
}

Risposte:


191

Ottima domanda. Uso uno schema come questo per la maggior parte dei miei script:

#!/bin/bash

main() {
    foo
    bar
    baz
}

foo() {
}

bar() {
}

baz() {
}

main "$@"

Puoi leggere il codice dall'alto verso il basso, ma in realtà non inizia l'esecuzione fino all'ultima riga. Passando "$@"al main () è possibile accedere agli argomenti della riga di comando $1, $2et al proprio come si farebbe normalmente.


3
Ciao, come strutturi i dati che devono essere condivisi tra foo / bar / baz nel tuo esempio? Di solito lo metto solo all'inizio della sceneggiatura. È ancora così quando si usano le funzioni? O è meglio mettere i dati globali in main e poi passarli a foo / bar / baz come argomenti? Qual è la migliore pratica?
bodacydo

4
Preferisco gli argomenti. Salvo ciò, imposterò le variabili globali in maino in una funzione subito dopo main(ad esempio, setupo parseArguments). Evito di avere variabili globali impostate sopra main- il codice non dovrebbe uscire da main.
John Kugelman

Questo sembra in qualche modo analogo a ciò che if _ _ name _ _ == "_ _ main _ _": main()fa in Python
Sergiy Kolodyazhnyy

Questo è fantastico anche quando si utilizzano strumenti come Bats per testare i propri script, suddividere tutto in funzioni rende molto più semplice il test dei singoli componenti. Vedi anche il post del blog
dragon788

31

Quando i miei script bash crescono troppo, utilizzo un meccanismo di inclusione:

File allMyFunctions:

foo() {
}

bar() {
}

baz() {
}

File main:

#!/bin/bash

. allMyfunctions

foo
bar
baz

28
Personalmente, quando uno script di shell inizia a crescere oltre un file, tendo a passare a una lingua diversa ;-)
Joachim Sauer

Non sarebbe meglio usare source allMyfunctions?
pydoge

4
@pydoge: sourcenon è conforme a POSIX. bashdefinisce sourcecome un alias a .: sono funzionalmente equivalenti.
mouviciel
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.