Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

การทำความเข้าใจและการเขียนฟังก์ชันในเชลล์สคริปต์ – ตอนที่ VI

ฟังก์ชันมีบทบาทสำคัญในภาษาการเขียนโปรแกรมใดๆ เช่นเดียวกับภาษาโปรแกรมจริงหลายๆ ภาษา bash มีฟังก์ชันที่ใช้กับการใช้งานที่จำกัด

การทำความเข้าใจและการเขียนฟังก์ชันในเชลล์สคริปต์ – ตอนที่ VI

หน้าที่คืออะไร

ในการเขียนโปรแกรม ฟังก์ชันจะตั้งชื่อว่าส่วนต่างๆ ของโปรแกรมที่ทำงานเฉพาะ ในแง่นี้ ฟังก์ชันคือประเภทของขั้นตอนหรือกิจวัตร เมื่อเรียกใช้ฟังก์ชัน โปรแกรมจะออกจากส่วนปัจจุบันของโค้ดและเริ่มดำเนินการบรรทัดแรกภายในฟังก์ชัน เมื่อใดก็ตามที่มีโค้ดซ้ำๆ หรือเมื่องานเกิดซ้ำ ให้พิจารณาใช้ฟังก์ชันแทน

ตัวอย่างเช่น พิจารณากรณีที่เราต้องค้นหาแฟกทอเรียลของตัวเลขในหลายขั้นตอนของโปรแกรมหนึ่งๆ แทนที่จะเขียนโค้ดทั้งหมด (สำหรับคำนวณแฟคทอเรียล) ทุกครั้ง เราสามารถเขียนโค้ดส่วนนั้นซึ่งคำนวณแฟคทอเรียลครั้งเดียวภายในบล็อกและนำกลับมาใช้ซ้ำได้หลายครั้ง

ทำไมเราถึงเขียนฟังก์ชัน

  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 ถ้าบรรทัดสำหรับการตรวจสอบความถูกต้อง เช่น เพื่อตรวจสอบจำนวนและประเภทของอาร์กิวเมนต์ด้วยความช่วยเหลือของนิพจน์ทั่วไป หลังจากนั้นเราเรียกใช้ฟังก์ชันด้วยอาร์กิวเมนต์บรรทัดคำสั่งสองอาร์กิวเมนต์และแสดงผลที่นั่น เนื่องจากเราไม่สามารถคืนค่าจำนวนเต็มขนาดใหญ่จากฟังก์ชันได้ อีกวิธีในการแก้ไขปัญหานี้คือการใช้ตัวแปรส่วนกลางเพื่อเก็บผลลัพธ์ไว้ในฟังก์ชัน สคริปต์ด้านล่างอธิบายวิธีการนี้

#!/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 ขั้นพื้นฐาน – ตอนที่ 1
  2. 5 เชลล์สคริปต์สำหรับมือใหม่ Linux เพื่อเรียนรู้การเขียนโปรแกรมเชลล์ – ตอนที่ II
  3. ท่องโลกของ Linux BASH Scripting – ตอนที่ III
  4. แง่มุมทางคณิตศาสตร์ของการเขียนโปรแกรม Linux Shell – ส่วนที่ IV
  5. การคำนวณนิพจน์ทางคณิตศาสตร์ในภาษาสคริปต์ของเชลล์ – ตอนที่ V

ฉันจะกลับมาพร้อมข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับคุณสมบัติการทำงาน เช่น การใช้ตัวแปรในเครื่อง การเรียกซ้ำ ฯลฯ ในส่วนถัดไป ปรับปรุงอยู่กับความคิดเห็น