GNU/Linux >> Linux Esercitazione >  >> Linux

Bash Scripting:funzioni spiegate con esempi

Nello scripting della shell Bash, le funzioni sono modi per raggruppare insieme l'insieme di istruzioni per ottenere un risultato specifico. Puoi pensare alle funzioni come a un mini script. Le funzioni sono anche chiamate procedure e metodi in alcuni linguaggi di programmazione. Le funzioni sono un ottimo modo per ottenere modularità e riutilizzabilità.

In questo articolo, spiegherò come utilizzare le funzioni negli script bash in Linux con esempi. Ti sentirai abbastanza a tuo agio nell'usare le funzioni bash entro la fine di questo articolo.

Come definire le funzioni in Bash

Ci sono due cose importanti che devi capire quando lavori con le funzioni.

  • Definizione della funzione,
  • Chiamare la funzione.

In modo simile a come crei gli script bash e li esegui, dovresti definire la funzione e chiamarla per l'esecuzione della funzione.

Esistono due modi sintattici per definire una funzione in bash. Il primo modo è usare la parola chiave incorporata in bash "function" seguito dal nome della funzione. Il blocco di codice verrà scritto tra parentesi graffe {} .

function [name] {
Block of code
}

Il secondo modo è creare una funzione senza la parola chiave "function" . Inizia con il nome della funzione seguito da parentesi.

[name](){
Block of Code
}

Quale scegliere? Beh, è ​​sempre una scelta personale. La scelta dell'uno rispetto all'altro non ha inconvenienti.

Puoi anche scrivere funzioni a riga singola che sono chiamate funzioni compatte . Nelle funzioni compatte, ogni riga di codice tra parentesi graffe è separata da un punto e virgola (; ) .

Avvia il tuo terminale e scrivi un pezzo di funzione multilinea. Ora premi il tasto freccia su e vedrai tutto ciò che hai scritto su più righe verrà convertito in funzioni compatte.

[name](){ first_line; second_line; }

MIGLIOR PRATICA:

  1. Cerca di scegliere una sintassi qualsiasi e di essere coerente con essa.
  2. Se lavori in un ambiente collaborativo, è importante che tutti mantengano lo stesso standard durante la codifica.

Convenzione di denominazione

Quando crei una funzione devi dare un nome alla tua funzione. Il nome della funzione deve essere descrittivo e cercare di evitare nomi già utilizzati da altre funzioni, variabili, costanti, ecc. "Snake Case" è il modo preferito per denominare la funzione. Nel caso del serpente, le parole sono separate da trattini bassi.

Dai un'occhiata all'esempio qui sotto. Ho creato una funzione denominata "hello_world" in stile serpente che stamperà semplicemente ciao mondo su stdout (Terminale).

hello_world() {
echo "Running Simple Hello World Function"
}

hello_world

Come chiamare una funzione in Bash

Creiamo una semplice funzione di pulizia denominata "log_cleanup" . Lo scopo di questa funzione è rimuovere ".log" file che sono più vecchi di 30 giorni.

log_cleanup(){
  echo "Running Cleanup On Older Logs - 30 days"
  find /home/karthick/Documents/Projects/logs/ -name "*.log" -type f -mtime +30 -delete
  echo "Cleanup Completed"
}

La funzione è definita, ma sarà sufficiente perché la funzione faccia il suo lavoro? Assolutamente no. È necessario chiamare la funzione per eseguire la funzione.

Per chiamare la funzione, digita semplicemente il nome della funzione dopo la definizione della funzione:

#!/usr/bin/env bash

#### FUNCTION DEFINITION ####

log_cleanup(){
  echo "Running Cleanup On Older Logs - 30 days"
  find /home/karthick/Documents/Projects/logs -name "*.log" -type f -mtime +30 -delete 
  echo "Cleanup Completed"
}

# Calling the function

log_cleanup  

Se provi a chiamare la funzione prima della definizione della funzione, otterrai il seguente errore.

line 3: log_cleanup: command not found

Perchè così? Quando esegui lo script, il codice verrà interpretato riga per riga dall'alto verso il basso. Leggerà la funzione e la caricherà nell'ambiente bash (memoria). Ma qui stai chiamando la funzione prima ancora che l'interprete legga e carichi la funzione nel suo ambiente.

Quando chiami una funzione dall'interno di un'altra funzione, la definizione della tua funzione può essere in qualsiasi ordine eccetto la prima funzione. Dai un'occhiata all'immagine qui sotto. Funzione funzione2 viene chiamato da func1 e func3 viene chiamato da func2 prima della loro definizione. Ma func1 viene prima definito e poi chiamato. Per il momento func1 viene chiamato tutte le definizioni delle funzioni sono già interpretate e caricate nell'ambiente.

Stato di uscita e valore di ritorno

Ogni comando Linux restituisce uno stato di uscita (0-255). Si dice che zero abbia successo e che il resto dei codici di uscita siano fallimenti con significati diversi. Allo stesso modo, quando esegui una funzione, restituisce anche uno stato di uscita dell'ultimo comando eseguito nella funzione.

Fammi eseguire di nuovo la stessa funzione di "pulizia". Ma ho fornito un percorso che non è disponibile nella mia macchina, quindi find comando fallirà. Sto usando $? per ottenere lo stato di uscita all'interno dello script come mostrato nell'immagine.

Running Cleanup On Older Logs - 30 days
find: '/home/karthick/Documents/Projectss/logs': No such file or directory
Cleanup Completed
Exit status of function log_cleanup is ⇒ 0

Lo stato di uscita restituito dalla funzione è da echo comando eseguito come ultimo comando all'interno della funzione. Questo non è il comportamento che potresti aspettarti.

Per superare questo comportamento puoi usare il bash integrato "return" dichiarazione.

$ type -a return
return is a shell builtin

Return accetta un valore intero [N] ed esce dalle funzioni e fornisce il valore restituito al suo chiamante (funzione). Prima di utilizzare la dichiarazione di ritorno, è necessario comprendere alcune regole su come utilizzare la dichiarazione di ritorno. Come affermato in precedenza, return accetta valori interi da 0 a 255. Un'istruzione return utilizzerà lo stato di uscita dell'ultimo comando eseguito se non viene passato alcun argomento (valore intero) o se il valore supera 255.

Fammi usare il ritorno per correggere il "cleanup" comportamento della funzione. Qui sto usando le istruzioni condizionali insieme al comando di ritorno.

#!/usr/bin/env bash

#### FUNCTION DEFINITION ####

log_cleanup(){
 echo "[ INFO ] - Running Cleanup On Older Logs - 30 days"
 if [[ -d "/home/karthick/Documents/Projectss/logs" ]]
 then
   find -name "*.log" -type f -mtime +30 -delete
   echo "[ SUCCESS] - Cleanup Completed"
 else
   echo "[ ERROR ] - Directory path wrong... Cleanup has not happened..."
   return 1
 fi
}

# Calling the function

log_cleanup 
echo "++ Exit status of log_cleanup function is ==> $?"

Dai un'occhiata all'output qui sotto. La funzione restituisce il codice di uscita 1 dalla dichiarazione di reso.

[ INFO ] - Running Cleanup On Older Logs - 30 days
[ ERROR ] - Directory path wrong… Cleanup has not happened…
++ Exit status of log_cleanup function is ==> 1

Passaggio di argomenti a una funzione

Simile al passaggio di argomenti ai tuoi script bash, anche le funzioni accettano argomenti. La parte confusa è che le funzioni usano lo stesso $1$9 variabili speciali per accedere agli argomenti che equivale a passare l'argomento allo script. Devi capire cosa succede quando usi questa variabile speciale all'interno e all'esterno della funzione.

cat > arg_test.sh
#!/bin/bash
echo "Value passed in \$1 is = $1"

howdy(){
   echo "value of \$1 inside function is = $1"
}

howdy # Function Call

Copia ed esegui lo snippet sopra per vedere la differenza. La stringa "Howdy" viene passato come primo argomento allo script.

$ ./arg_test.sh howdy
Value passed in $1 is = howdy
value of $1 inside function is =

Dall'output, puoi vedere $1 all'interno della funzione sta stampando un valore vuoto perché $1 all'interno della funzione è diverso da $1 al di fuori della funzione sebbene condividano lo stesso nome.

Per passare argomenti alla funzione, dopo il nome della funzione lascia uno spazio e passa i tuoi argomenti come mostrato nell'immagine sottostante. Ad ogni argomento separato da spazio verrà assegnata la rispettiva variabile $1$N e puoi usare questa variabile all'interno della funzione per elaborare gli argomenti.

log_cleanup $1 $2 ….. $N

Come puoi vedere nello screenshot sopra, sto passando il nome della directory e il numero di giorni come argomenti.

Ambito variabile per una funzione

Quando si crea una variabile all'interno o all'esterno della funzione, è possibile accedervi globalmente. Per impostazione predefinita, le variabili vengono create nell'ambito globale.

Dai un'occhiata all'esempio qui sotto. Se provi ad accedere sia alla variabile outside_function e inside_function , i loro valori sono accessibili. Ciò significa che anche se la funzione è stata eseguita ed è uscita, la variabile creata all'interno della funzione è accessibile a livello globale.

 #!/bin/bash

outside_function="This variable is from outside the function"

func1(){
  inside_function="This variable is from inside the func1"
}

func1
echo $outside_function
echo $inside_function

In alcuni linguaggi di programmazione, questo potrebbe non essere il comportamento e le variabili create all'interno della funzione saranno disponibili durante il runtime della funzione. Ma in bash, il comportamento è diverso.

Per rendere le variabili locali alla funzione puoi usare il built-in bash "local" parola chiave. La parola chiave local limiterà l'ambito della variabile da globale a locale e sarà possibile accedere alla variabile solo durante il runtime della funzione.

#!/bin/bash

outside_function="This variable is from outside the function"

func1(){
  local inside_function="This variable is from inside the func1"
}

func1
echo $outside_function
echo $inside_function

Lettura consigliata:

  • Scripting Bash:variabili spiegate con esempi

Quando viene utilizzata la parola chiave locale, puoi utilizzare gli stessi nomi di variabile in diverse funzioni.

Avviso: Dovresti sempre cercare di evitare di usare identificatori che sono già usati come variabili, funzioni, parole chiave bash. L'esempio sopra viene mostrato solo per comprendere il comportamento.

Modularità e Risubaility

Le funzioni di comprensione e scrittura possono essere eseguite in tempi rapidi. Ma scrivere buone funzioni richiede tempo con una migliore comprensione dell'ambiente. Come già sottolineato nella sezione introduttiva, con le funzioni bash puoi ottenere una grande modularità e riutilizzabilità.

Facciamo un esempio. Hai creato 20 script e in ogni script hai incluso il log_cleanup funzione che abbiamo visto nelle sezioni precedenti per svolgere compiti di pulizia. Invece di includere questa funzione in tutti i 20 script, puoi creare un'unica definizione di funzione e importarla in 20 script. In questo modo si ottengono modularità e funzioni riutilizzabili. È simile a importazione dichiarazioni in Python, includi affermazioni in C, ecc.

Dai un'occhiata all'immagine qui sotto. Ho creato due script chiamati script1.sh e script2.sh e il log_cleanup la funzione viene scritta in un file separato chiamato cleanup.sh .

Sto importando la funzione eseguendo source comando. Il source comando eseguirà il file passato come argomento e caricherà la variabile o le funzioni nella sessione bash corrente. In questo modo quando esegui log_cleanup da un altro file di script la funzione è già caricata nell'ambiente corrente ed è accessibile.

Dall'immagine sopra, puoi capire come gli argomenti sono utili. C'è solo una definizione di funzione e, in base al caso d'uso, posso modificare la funzione per accettare argomenti diversi e in script diversi.

Avviso: Puoi anche eseguire i tuoi script di shell con source comando che eseguirà lo script nella shell corrente invece di creare una subshell per eseguire lo script.

Conclusione

In questa guida, abbiamo discusso delle funzioni Bash e di come definire e chiamare una funzione negli script con esempi. Per familiarizzare con le funzioni, devi esercitarti con le funzioni con diversi casi d'uso. Se hai domande o feedback, non esitare a farcelo sapere tramite la sezione commenti qui sotto.

Lettura correlata:

  • Scripting Bash:il ciclo For viene spiegato con esempi
  • Scripting di Bash:spiegazione del ciclo While e Until con esempi
  • Differenza tra la definizione di variabili Bash con e senza esportazione
  • Comando Bash Echo spiegato con esempi in Linux
  • Tutorial Bash Heredoc per principianti
  • Il reindirizzamento di Bash spiegato con esempi

Linux
  1. Come scrivere uno script Bash con esempi

  2. Funzioni Bash

  3. Shell Scripting Parte V:Funzioni in Bash

  4. Funzioni nelle variabili Shell?

  5. Bash Istruzione If-Else con esempi

Il comando Tr in Linux spiegato con esempi

Bash Scripting Part6 – Crea e usa le funzioni Bash

Bash Scripting Part2 – Cicli For e While con esempi

Bash Scripting Introduzione Tutorial con 5 esempi pratici

Tutorial sulle funzioni di Bash Shell con 6 esempi pratici

Script Bash per Loop spiegato con esempi