Ricerca nel sito web

Comprensione e scrittura di funzioni negli script di shell - Parte VI


Le funzioni svolgono un ruolo importante in qualsiasi linguaggio di programmazione. Come molti linguaggi di programmazione reali, bash ha funzioni che vengono utilizzate con un'implementazione limitata.

Cosa sono le funzioni?

Nella programmazione, le funzioni sono sezioni denominate di un programma che esegue un compito specifico. In questo senso, una funzione è un tipo di procedura o routine. Quando viene chiamata una funzione il programma lascia la sezione corrente di codice e inizia ad eseguire la prima riga all'interno della funzione. Ogni volta che è presente un codice ripetitivo o quando un'attività si ripete, considera invece l'utilizzo di una funzione.

Ad esempio, considera il caso in cui dobbiamo trovare il fattoriale di un numero in diverse fasi di un particolare programma. Invece di scrivere ogni volta l'intero codice (per calcolare il fattoriale), possiamo scrivere quella parte di codice che calcola il fattoriale una volta all'interno di un blocco e riutilizzare la stessa in più occasioni.

Perché scriviamo funzioni?

  1. Ci aiuta a riutilizzare il codice.
  2. Migliorare la leggibilità del programma.
  3. Uso efficiente delle variabili all'interno del programma.
  4. Ci permette di testare il programma parte per parte.
  5. Visualizza il programma come una serie di passaggi secondari.
Funzioni negli script di shell

La sintassi generale per scrivere funzioni nello script di shell include i seguenti modi.

function func_name {
	. . .
	commands
	. . .
}

or

func_name ( ) {
	. . .
	commands
	. . .
}

Opening curly braces can also be used in the second line as well.

func_name ( )
{
	. . .
	commands
	. . .
}

Sei sempre libero di scrivere comandi validi all'interno di questi blocchi funzione come facciamo normalmente negli script di shell. Ora proviamo a scrivere un semplice script con una piccola funzione al suo interno.

#!/bin/bash

call_echo ( ) {
	echo ‘This is inside function’
}

op=$1

if [ $# -ne 1 ]; then
	echo "Usage: $0 <1/0>"
else
	if [ $1 = 0 ] ; then
		echo ‘This is outside function’
	elif [ $1 = 1 ] ; then
		call_echo
	else
		echo ‘Invalid argument’
	fi
fi

exit 0

La definizione della funzione deve precedere la prima chiamata ad essa. Non c’è niente come “dichiarare la funzione” prima di chiamarla. E possiamo sempre annidare funzioni all'interno di funzioni.

Nota:- La scrittura di funzioni vuote provoca sempre errori di sintassi.

Quando la stessa funzione viene definita più volte, la versione finale è quella che viene invocata. Facciamo un esempio.

#!/bin/bash

func_same ( ) {
	echo ‘First definition’
}

func_same ( ) {
	echo ‘Second definition’
}

func_same

exit 0
Funzioni che accettano parametri e restituiscono valori

Andiamo più in profondità considerando le funzioni che accettano parametri e restituiscono valori. Per restituire un valore da una funzione utilizziamo la shell integrata "return". La sintassi è la seguente.

func_name ( ) {
	. . .
	commands
	. . .
	return $ret_val
}

Allo stesso modo possiamo passare argomenti alle funzioni separate da spazi come indicato di seguito.

func_name $arg_1 $arg_2 $arg_3

All'interno della funzione possiamo accedere agli argomenti nell'ordine $1, $2, $3 e così via. Guarda il seguente script di esempio per trovare il massimo di due numeri interi utilizzando la funzione per aggiungere maggiore chiarezza.

#!/bin/bash

USG_ERR=7

max_two ( ) {
	if [ "$1" -eq "$2" ] ; then
		echo 'Equal'
		exit 0
	elif [ "$1" -gt "$2" ] ; then
		echo $1
	else
		echo $2
	fi
}

err_str ( ) {
	echo "Usage: $0 <number1>  <number2>"
	exit $USG_ERR
}

NUM_1=$1
NUM_2=$2
x
if [ $# -ne 2 ] ; then
	err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
	if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then  
		max_two $NUM_1 $NUM_2
	else
		err_str
	fi
else
	err_str
fi

exit 0

Quanto sopra sembra un po’ complesso, ma è semplice se leggiamo le righe. Prima le righe if-else if nidificate per scopi di convalida, ovvero per verificare il numero e il tipo di argomenti con l'aiuto di espressioni regolari. Successivamente chiamiamo la funzione con due argomenti della riga di comando e visualizziamo il risultato stesso. Questo perché non possiamo restituire numeri interi di grandi dimensioni da una funzione. Un altro modo per aggirare questo problema è utilizzare variabili globali per memorizzare il risultato all'interno della funzione. Lo script seguente spiega questo metodo.

#!/bin/bash

USG_ERR=7
ret_val=

max_two ( ) {
	if [ "$1" -eq "$2" ] ; then
		echo 'Equal'
		exit 0
	elif [ "$1" -gt "$2" ] ; then
		ret_val=$1
	else
		ret_val=$2
	fi
}

err_str ( ) {
	echo "Usage: $0 <number1>  <number2>"
	exit $USG_ERR
}

NUM_1=$1
NUM_2=$2

if [ $# -ne 2 ] ; then
	err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
	if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then  
		max_two $NUM_1 $NUM_2
		echo $ret_val
	else
		err_str
	fi
else
	err_str
fi

exit 0

Ora prova alcuni problemi interessanti che sono stati spiegati nella precedente serie di scripting di shell utilizzando le funzioni come segue.

  1. Comprendere i suggerimenti di base sul linguaggio di scripting della shell Linux - Parte I
  2. 5 script di shell per principianti di Linux per imparare la programmazione di shell - Parte II
  3. Navigando nel mondo di Linux BASH Scripting – Parte III
  4. Aspetti matematici della programmazione della shell Linux - Parte IV
  5. Calcolo delle espressioni matematiche nel linguaggio di scripting della shell - Parte V

Tornerò con maggiori informazioni sulle caratteristiche funzionali come l'utilizzo di variabili locali, ricorsione, ecc. nella parte successiva. Rimani aggiornato con i commenti.