Κατανόηση και γραφή συναρτήσεων σε Shell Scripts - Μέρος VI


Οι συναρτήσεις παίζουν σημαντικό ρόλο σε οποιαδήποτε γλώσσα προγραμματισμού. Όπως πολλές πραγματικές γλώσσες προγραμματισμού, το bash έχει λειτουργίες που χρησιμοποιούνται με περιορισμένη υλοποίηση.

Τι είναι οι συναρτήσεις;

Στον προγραμματισμό, οι συναρτήσεις ονομάζονται τμήματα ενός προγράμματος που εκτελεί μια συγκεκριμένη εργασία. Υπό αυτή την έννοια, μια συνάρτηση είναι ένας τύπος διαδικασίας ή ρουτίνας. Όταν καλείται μια συνάρτηση, το πρόγραμμα φεύγει από την τρέχουσα ενότητα κώδικα και αρχίζει να εκτελεί την πρώτη γραμμή μέσα στη συνάρτηση. Κάθε φορά που υπάρχει επαναλαμβανόμενος κώδικας ή όταν μια εργασία επαναλαμβάνεται, σκεφτείτε να χρησιμοποιήσετε μια συνάρτηση.

Για παράδειγμα, εξετάστε την περίπτωση όπου πρέπει να βρούμε το παραγοντικό ενός αριθμού σε διάφορα στάδια ενός συγκεκριμένου προγράμματος. Αντί να γράφουμε ολόκληρο τον κώδικα (για τον υπολογισμό του παραγοντικού) κάθε φορά, μπορούμε να γράφουμε εκείνο το τμήμα του κώδικα που υπολογίζει το παραγοντικό μία φορά μέσα σε ένα μπλοκ και να το επαναχρησιμοποιούμε σε πολλές περιπτώσεις.

Γιατί γράφουμε συναρτήσεις;

  1. Μας βοηθά να χρησιμοποιήσουμε ξανά τον κώδικα.
  2. Βελτιώστε την αναγνωσιμότητα του προγράμματος.
  3. Αποτελεσματική χρήση μεταβλητών μέσα στο πρόγραμμα.
  4. Μας επιτρέπει να δοκιμάσουμε το πρόγραμμα μέρος προς μέρος.
  5. Εμφανίζει το πρόγραμμα ως μια δέσμη δευτερευόντων βημάτων.
Λειτουργίες σε σενάρια φλοιού

Η γενική σύνταξη για τη γραφή συναρτήσεων σε σενάριο φλοιού περιλαμβάνει τους ακόλουθους τρόπους.

function func_name {
	. . .
	commands
	. . .
}

or

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

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

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

Είστε πάντα ελεύθεροι να γράφετε έγκυρες εντολές μέσα σε αυτά τα μπλοκ συναρτήσεων όπως κάνουμε συνήθως στα σενάρια φλοιού. Τώρα ας προσπαθήσουμε να γράψουμε ένα απλό σενάριο με μια μικρή συνάρτηση μέσα του.

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

Ο ορισμός της συνάρτησης πρέπει να προηγείται της πρώτης κλήσης σε αυτήν. Δεν υπάρχει τίποτα σαν τη «δήλωση της συνάρτησης» πριν την καλέσετε. Και μπορούμε πάντα να ενθέτουμε συναρτήσεις μέσα σε συναρτήσεις.

Σημείωση:- Η εγγραφή κενών συναρτήσεων οδηγεί πάντα σε συντακτικά σφάλματα.

Όταν η ίδια συνάρτηση ορίζεται πολλές φορές, η τελική έκδοση είναι αυτή που καλείται. Ας πάρουμε ένα παράδειγμα.

#!/bin/bash

func_same ( ) {
	echo ‘First definition’
}

func_same ( ) {
	echo ‘Second definition’
}

func_same

exit 0
Λειτουργίες που λαμβάνουν παραμέτρους και επιστρέφουν τιμές

Ας εμβαθύνουμε εξετάζοντας συναρτήσεις που λαμβάνουν παραμέτρους και επιστρέφουν τιμές. Για να επιστρέψουμε μια τιμή από μια συνάρτηση χρησιμοποιούμε το ενσωματωμένο κέλυφος «return». Η σύνταξη έχει ως εξής.

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

Παρομοίως μπορούμε να περάσουμε ορίσματα στις συναρτήσεις διαχωρισμένες με κενά όπως δίνεται παρακάτω.

func_name $arg_1 $arg_2 $arg_3

Μέσα στη συνάρτηση μπορούμε να έχουμε πρόσβαση στα ορίσματα με τη σειρά ως $1, $2, $3 και ούτω καθεξής. Κοιτάξτε το παρακάτω παράδειγμα δέσμης ενεργειών για να βρείτε το μέγιστο των δύο ακεραίων χρησιμοποιώντας τη συνάρτηση για να προσθέσετε περισσότερη σαφήνεια.

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

Τα παραπάνω φαίνονται λίγο περίπλοκα, αλλά είναι απλό αν διαβάσουμε μέσα από τις γραμμές. Πρώτα ένθετες γραμμές if-else if για σκοπούς επικύρωσης, π.χ., για έλεγχο του αριθμού και του τύπου των ορισμάτων με τη βοήθεια κανονικών παραστάσεων. Μετά από αυτό καλούμε τη συνάρτηση με δύο ορίσματα γραμμής εντολών και εμφανίζει το ίδιο το αποτέλεσμα εκεί. Αυτό συμβαίνει επειδή δεν μπορούμε να επιστρέψουμε μεγάλους ακέραιους από μια συνάρτηση. Ένας άλλος τρόπος για να επιλύσετε αυτό το πρόβλημα είναι να χρησιμοποιήσετε καθολικές μεταβλητές για να αποθηκεύσετε το αποτέλεσμα μέσα στη συνάρτηση. Το παρακάτω σενάριο εξηγεί αυτή τη μέθοδο.

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

Τώρα δοκιμάστε μερικά συναρπαστικά προβλήματα που εξηγήθηκαν στην προηγούμενη σειρά σεναρίων κελύφους χρησιμοποιώντας τις παρακάτω λειτουργίες.

  1. Κατανοήστε τις βασικές συμβουλές γλώσσας δέσμης ενεργειών Linux Shell – Μέρος I
  2. 5 Σενάρια Shell για αρχάριους Linux για να μάθουν προγραμματισμό Shell – Μέρος II
  3. Sailing Through The World of Linux BASH Scripting – Μέρος III
  4. Μαθηματική πτυχή του προγραμματισμού κελύφους Linux – Μέρος IV
  5. Υπολογισμός μαθηματικών εκφράσεων σε γλώσσα δέσμης ενεργειών - Μέρος V

Θα επανέλθω με περισσότερες πληροφορίες για λειτουργικά χαρακτηριστικά όπως η χρήση τοπικών μεταβλητών, η αναδρομή κ.λπ. στο επόμενο μέρος. Μείνετε ενημερωμένοι με σχόλια.