Zoeken op website

Functies in Shell-scripts begrijpen en schrijven - Deel VI


Functies spelen een belangrijke rol in elke programmeertaal. Zoals veel echte programmeertalen heeft bash functies die met een beperkte implementatie worden gebruikt.

Wat zijn functies?

Bij het programmeren worden functies secties genoemd van een programma dat een specifieke taak uitvoert. In deze zin is een functie een soort procedure of routine. Wanneer een functie wordt aangeroepen, verlaat het programma het huidige codegedeelte en begint de eerste regel binnen de functie uit te voeren. Wanneer er sprake is van repetitieve code of wanneer een taak zich herhaalt, overweeg dan om in plaats daarvan een functie te gebruiken.

Beschouw bijvoorbeeld het geval waarin we de faculteit van een getal moeten vinden in verschillende fasen van een bepaald programma. In plaats van elke keer de hele code te schrijven (voor het berekenen van de faculteit), kunnen we dat deel van de code schrijven dat de faculteit eenmaal in een blok berekent en dit meerdere keren hergebruikt.

Waarom schrijven we functies?

  1. Het helpt ons de code opnieuw te gebruiken.
  2. Verbeter de leesbaarheid van het programma.
  3. Efficiënt gebruik van variabelen binnen het programma.
  4. Hiermee kunnen we het programma onderdeel voor onderdeel testen.
  5. Geeft het programma weer als een aantal substappen.
Functies in shellscripts

De algemene syntaxis voor het schrijven van functies in shellscript omvat de volgende manieren.

function func_name {
	. . .
	commands
	. . .
}

or

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

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

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

U bent altijd vrij om geldige opdrachten binnen deze functieblokken te schrijven, zoals we dat normaal gesproken doen in shell-scripts. Laten we nu proberen een eenvoudig script te schrijven met een kleine functie erin.

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

De functiedefinitie moet voorafgaan aan de eerste aanroep ervan. Er gaat niets boven het ‘declareren van de functie’ voordat deze wordt aangeroepen. En we kunnen functies altijd binnen functies nesten.

Opmerking:- Het schrijven van lege functies resulteert altijd in syntaxisfouten.

Wanneer dezelfde functie meerdere keren wordt gedefinieerd, wordt de definitieve versie aangeroepen. Laten we een voorbeeld nemen.

#!/bin/bash

func_same ( ) {
	echo ‘First definition’
}

func_same ( ) {
	echo ‘Second definition’
}

func_same

exit 0
Functies die parameters aannemen en waarden retourneren

Laten we dieper ingaan op functies die parameters aannemen en waarden retourneren. Om een waarde uit een functie terug te geven, gebruiken we de ingebouwde ‘return’-shell. De syntaxis is als volgt.

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

Op dezelfde manier kunnen we argumenten doorgeven aan de functies, gescheiden door spaties, zoals hieronder weergegeven.

func_name $arg_1 $arg_2 $arg_3

Binnen de functie hebben we toegang tot de argumenten in de volgorde $1, $2, $3 enzovoort. Bekijk het volgende voorbeeldscript om het maximum van twee gehele getallen te vinden met behulp van de functie om meer duidelijkheid toe te voegen.

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

Het bovenstaande lijkt een beetje ingewikkeld, maar het is eenvoudig als we de regels doorlezen. Eerst geneste if-else if-regels voor validatiedoeleinden, dat wil zeggen om het aantal en type argumenten te controleren met behulp van reguliere expressies. Daarna roepen we de functie aan met twee opdrachtregelargumenten en geven daar het resultaat zelf weer. Dit komt omdat we geen grote gehele getallen uit een functie kunnen retourneren. Een andere manier om dit probleem te omzeilen is door globale variabelen te gebruiken om het resultaat in de functie op te slaan. In het onderstaande script wordt deze methode uitgelegd.

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

Probeer nu een aantal opwindende problemen uit die in de vorige serie shellscripts zijn uitgelegd, met behulp van de volgende functies.

  1. Begrijp de basistips voor Linux Shell-scripttaal – Deel I
  2. 5 Shell-scripts voor Linux-nieuwkomers om Shell-programmering te leren - Deel II
  3. Zeilen door de wereld van Linux BASH-scripting – Deel III
  4. Wiskundig aspect van Linux Shell-programmering – Deel IV
  5. Wiskundige uitdrukkingen berekenen in Shell-scripttaal – Deel V

In het volgende deel kom ik terug met meer inzicht in functionele kenmerken, zoals het gebruik van lokale variabelen, recursie enz. Blijf op de hoogte van reacties.