Wyszukiwanie w witrynie

Zrozumienie i zapisanie funkcji w skryptach powłoki - Część VI


Funkcje odgrywają ważną rolę w każdym języku programowania. Podobnie jak wiele innych prawdziwych języków programowania, bash posiada funkcje, których użycie jest ograniczone.

Co to są funkcje?

W programowaniu funkcje są nazwanymi sekcjami programu, które wykonują określone zadanie. W tym sensie funkcja jest rodzajem procedury lub procedury. Kiedy funkcja jest wywoływana, program opuszcza bieżącą sekcję kodu i zaczyna wykonywać pierwszą linię wewnątrz funkcji. Ilekroć kod się powtarza lub zadanie się powtarza, rozważ zamiast tego użycie funkcji.

Rozważmy na przykład przypadek, w którym musimy znaleźć silnię liczby na kilku etapach konkretnego programu. Zamiast za każdym razem pisać cały kod (do obliczania silni), możemy napisać tę część kodu, która oblicza silnię wewnątrz bloku i używać jej wielokrotnie.

Po co piszemy funkcje?

  1. Pomaga nam to w ponownym użyciu kodu.
  2. Popraw czytelność programu.
  3. Efektywne wykorzystanie zmiennych wewnątrz programu.
  4. Pozwala nam testować program część po części.
  5. Wyświetla program jako kilka podetapów.
Funkcje w skryptach powłoki

Ogólna składnia pisania funkcji w skrypcie powłoki obejmuje następujące sposoby.

function func_name {
	. . .
	commands
	. . .
}

or

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

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

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

Zawsze możesz pisać poprawne polecenia wewnątrz tych bloków funkcyjnych, tak jak robimy to zwykle w skryptach powłoki. Spróbujmy teraz napisać jeden prosty skrypt z małą funkcją w środku.

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

Definicja funkcji musi poprzedzać pierwsze jej wywołanie. Nie ma nic lepszego niż „deklarowanie funkcji” przed jej wywołaniem. Zawsze możemy zagnieździć funkcje wewnątrz funkcji.

Uwaga:- Zapisywanie pustych funkcji zawsze skutkuje błędami składniowymi.

Jeśli ta sama funkcja jest zdefiniowana wielokrotnie, wywoływana jest wersja ostateczna. Weźmy przykład.

#!/bin/bash

func_same ( ) {
	echo ‘First definition’
}

func_same ( ) {
	echo ‘Second definition’
}

func_same

exit 0
Funkcje pobierające parametry i zwracające wartości

Wejdźmy głębiej, rozważając funkcje pobierające parametry i zwracające wartości. Aby zwrócić wartość z funkcji, używamy wbudowanej powłoki „return”. Składnia jest następująca.

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

Podobnie możemy przekazywać argumenty do funkcji oddzielonych spacjami, jak podano poniżej.

func_name $arg_1 $arg_2 $arg_3

Wewnątrz funkcji możemy uzyskać dostęp do argumentów w kolejności 1 $, 2 $, 3 $i tak dalej. Przyjrzyj się poniższemu przykładowemu skryptowi, aby znaleźć maksymalnie dwie liczby całkowite za pomocą funkcji w celu zwiększenia przejrzystości.

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

Powyższe wygląda na nieco skomplikowane, ale stanie się proste, jeśli przeczytamy linijki. Najpierw zagnieżdżone linie if-else if do celów walidacji, tj. sprawdzenia liczby i typu argumentów za pomocą wyrażeń regularnych. Następnie wywołujemy funkcję z dwoma argumentami wiersza poleceń i wyświetlamy tam wynik. Dzieje się tak, ponieważ funkcja nie może zwrócić dużych liczb całkowitych. Innym sposobem obejścia tego problemu jest użycie zmiennych globalnych do przechowywania wyniku w funkcji. Poniższy skrypt wyjaśnia tę metodę.

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

Teraz wypróbuj kilka ekscytujących problemów, które zostały wyjaśnione w poprzedniej serii skryptów powłoki, używając poniższych funkcji.

  1. Zapoznaj się z podstawowymi wskazówkami dotyczącymi języka skryptowego powłoki systemu Linux — część I
  2. 5 skryptów powłoki dla początkujących w Linuksie do nauki programowania w powłoce – część II
  3. Żeglowanie po świecie skryptów Linux BASH – część III
  4. Matematyczny aspekt programowania w powłoce systemu Linux – część IV
  5. Obliczanie wyrażeń matematycznych w języku skryptowym powłoki – część V

W następnej części wrócę z większym wglądem w funkcje funkcjonalne, takie jak używanie zmiennych lokalnych, rekurencja itp. Bądź na bieżąco dzięki komentarzom.