Các hàm đóng một vai trò quan trọng trong bất kỳ ngôn ngữ lập trình nào. Giống như nhiều ngôn ngữ lập trình thực, bash có các hàm được sử dụng với việc triển khai hạn chế.
Chức năng là gì?
Trong lập trình, các hàm được đặt tên là các phần của chương trình thực hiện một nhiệm vụ cụ thể. Theo nghĩa này, một hàm là một loại thủ tục hoặc quy trình. Khi một hàm được gọi, chương trình sẽ rời khỏi đoạn mã hiện tại và bắt đầu thực hiện dòng đầu tiên bên trong hàm. Bất cứ khi nào có mã lặp lại hoặc khi một nhiệm vụ lặp lại, hãy cân nhắc sử dụng một hàm để thay thế.
Ví dụ, hãy xem xét trường hợp chúng ta cần tìm giai thừa của một số ở một số giai đoạn của một chương trình cụ thể. Thay vì viết toàn bộ mã (để tính giai thừa) mỗi lần, chúng ta có thể viết phần mã đó để tính giai thừa một lần bên trong một khối và sử dụng lại cùng một lúc nhiều lần.
Tại sao chúng ta viết hàm?
- Nó giúp chúng tôi sử dụng lại mã.
- Cải thiện khả năng đọc của chương trình.
- Sử dụng hiệu quả các biến bên trong chương trình.
- Cho phép chúng tôi kiểm tra từng phần chương trình.
- Hiển thị chương trình dưới dạng một loạt các bước phụ.
Các hàm trong tập lệnh shell
Cú pháp chung để viết các hàm trong shell script bao gồm các cách sau.
function func_name { . . . commands . . . } or func_name ( ) { . . . commands . . . } Opening curly braces can also be used in the second line as well. func_name ( ) { . . . commands . . . }
Bạn luôn có thể tự do viết các lệnh hợp lệ bên trong các khối chức năng này như chúng ta thường làm trong các tập lệnh shell. Bây giờ, hãy thử viết một tập lệnh đơn giản với một chức năng nhỏ bên trong nó.
#!/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
Định nghĩa hàm phải đặt trước lệnh gọi đầu tiên đến nó. Không có gì giống như ‘khai báo hàm’ trước khi gọi nó. Và chúng ta luôn có thể lồng các hàm vào bên trong các hàm.
Lưu ý :- Viết các hàm trống luôn dẫn đến lỗi cú pháp.
Khi cùng một chức năng được xác định nhiều lần, phiên bản cuối cùng là những gì được gọi. Hãy lấy một ví dụ.
#!/bin/bash func_same ( ) { echo ‘First definition’ } func_same ( ) { echo ‘Second definition’ } func_same exit 0
Các hàm lấy tham số và trả về giá trị
Hãy tìm hiểu sâu hơn bằng cách xem xét các hàm lấy tham số và trả về giá trị. Để trả về một giá trị từ một hàm, chúng tôi sử dụng trình bao ‘return’ được tích hợp sẵn. Cú pháp như sau.
func_name ( ) { . . . commands . . . return $ret_val }
Tương tự, chúng ta có thể truyền các đối số cho các hàm được phân tách bằng dấu cách như cho bên dưới.
func_name $arg_1 $arg_2 $arg_3
Bên trong hàm, chúng ta có thể truy cập các đối số theo thứ tự $ 1, $ 2, $ 3, v.v. Hãy xem tập lệnh ví dụ sau để tìm tối đa hai số nguyên bằng cách sử dụng hàm để thêm rõ ràng hơn.
#!/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
Ở trên có vẻ hơi phức tạp, nhưng sẽ đơn giản nếu chúng ta đọc sơ qua các dòng. Các dòng if-else if lồng nhau đầu tiên nhằm mục đích xác thực, tức là để kiểm tra số lượng và loại đối số với sự trợ giúp của các biểu thức chính quy. Sau đó, chúng ta gọi hàm với hai đối số dòng lệnh và hiển thị kết quả ở đó. Điều này là do chúng ta không thể trả về số nguyên lớn từ một hàm. Một cách khác để giải quyết vấn đề này là sử dụng các biến toàn cục để lưu trữ kết quả bên trong hàm. Tập lệnh bên dưới giải thích phương pháp này.
#!/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
Bây giờ, hãy thử một số vấn đề thú vị đã được giải thích trong loạt bài tập lệnh shell trước bằng cách sử dụng các hàm như sau.
- Hiểu Mẹo Ngôn ngữ Kịch bản Shell Cơ bản của Linux - Phần I
- 5 Tập lệnh Shell cho Người mới sử dụng Linux để Học Lập trình Shell - Phần II
- Đi khắp thế giới của Linux BASH Scripting - Phần III
- Khía cạnh Toán học của Lập trình Shell Linux - Phần IV
- Tính toán các biểu thức toán học trong ngôn ngữ kịch bản Shell - Phần V
Tôi sẽ trở lại với cái nhìn sâu sắc hơn về các tính năng chức năng như sử dụng biến cục bộ, đệ quy, v.v. trong phần tiếp theo. Luôn cập nhật các nhận xét.