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?
- Pomaga nam to w ponownym użyciu kodu.
- Popraw czytelność programu.
- Efektywne wykorzystanie zmiennych wewnątrz programu.
- Pozwala nam testować program część po części.
- 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.
- Zapoznaj się z podstawowymi wskazówkami dotyczącymi języka skryptowego powłoki systemu Linux — część I
- 5 skryptów powłoki dla początkujących w Linuksie do nauki programowania w powłoce – część II
- Żeglowanie po świecie skryptów Linux BASH – część III
- Matematyczny aspekt programowania w powłoce systemu Linux – część IV
- 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.