Thử viết shell script theo dạng hướng đối tượng
Bài đăng này đã không được cập nhật trong 7 năm
Bài viết được dịch từ nguồn http://hipersayanx.blogspot.com/2012/12/object-oriented-programming-in-bash.html
Bash rất phổ biến và đó là ngôn ngữ lập trình tập trung vào việc thực hiện lệnh. Lập trình hướng đối tượng (OOP) là một mô hình lập trình hướng tới một đối tượng với một tập các thuộc tính và hành động mà nó có thể thực hiện. Nếu bạn sử dụng Bash để viết các chương trình đơn giản và ngắn, lập trình thủ tục thì bạn không cần nhiều hơn. Nhưng nếu chương trình của bạn ngày càng trở nên lớn hơn, một chương trình to lớn (> 1000 dòng), thì bạn cần một cách tốt hơn để cấu trúc chương trình của bạn để giúp duy trì và đọc dễ dàng. Tất nhiên, Bash thiếu các tính năng OOP, nhưng với một số thủ thuật bạn có thể mô phỏng nó với một vài dòng được thêm vào, và tôi sẽ chỉ cho bạn làm thế nào.
Chú ý: Bạn cần có khái niệm vững chắc về OOP và Bash trước khi đọc, tôi sẽ không giải thích điều này ở đây.
Đầu tiên tạo ra một chương trình mà trong đó bạn sẽ xác định lớp đối tượng của bạn, và cho phép nó thực hiện các method
.
touch vector.sh
chmod +x vector.sh
Sau đó sao chép đoạn code sau:
#!/bin/bash
# Base class. (1)
function Vector()
{
# A pointer to this Class. (2)
base=$FUNCNAME
this=$1
# Inherited classes (optional). (3)
export ${this}_inherits="Class1 Class2 Class3" # (3.1)
for class in $(eval "echo \$${this}_inherits")
do
for property in $(compgen -A variable ${class}_)
do
export ${property/#$class\_/$this\_}="${property}" # (3.2)
done
for method in $(compgen -A function ${class}_)
do
export ${method/#$class\_/$this\_}="${method} ${this}"
done
done
# Declare Properties. (4)
export ${this}_x=$2
export ${this}_y=$3
export ${this}_z=$4
# Declare methods. (5)
for method in $(compgen -A function)
do
export ${method/#$base\_/$this\_}="${method} ${this}"
done
}
# Human readable representation of the vector. (6)
function Vector_show()
{
# (7)
base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
this=$1
x=$(eval "echo \$${this}_x")
y=$(eval "echo \$${this}_y")
z=$(eval "echo \$${this}_z")
echo "$this ($x, $y, $z)"
}
# Adds two vectors.
function Vector_add()
{
base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
this=$1
other=$2
# Get it's components
x1=$(eval "echo \$${this}_x")
y1=$(eval "echo \$${this}_y")
z1=$(eval "echo \$${this}_z")
x2=$(eval "echo \$${other}_x")
y2=$(eval "echo \$${other}_y")
z2=$(eval "echo \$${other}_z")
# Add it's components
x=$(($x1 + $x2))
y=$(($y1 + $y2))
z=$(($z1 + $z2))
# Create a new vector. (8)
Vector 'vector3' $x $y $z
$vector3_show
}
-
Đây hàm của một
class
. Nó phải có cùng tên củaclass
. Tên của mộtclass
không thể chứa dấu gạch dưới (_). Chúng ta sẽ sử dụng hàm này để tạo cácmethod
của lớp "Vector". -
Ở đây bạn có thể có được một
base class
của đối tượng và một tham chiếu của đối tượng được tạo ra. Đối số đầu tiên của hàm tạo phải luôn là tên của đối tượng để tạo ra. -
Khối
code
này mô phỏng thừa kế, bạn có thể gỡ bỏ nó nếu bạn không cần. 3.1. Mỗi thuộc tính và phương thức của lớp có thể được gọi như$ {this} _methodProperty_name
, hoặc bạn cũng có thể gọi nó là lớp cơ sở như$ {base} _methodProperty_name
. Nhiềuclass
thừa kếoveride
các phương thức và thuộc tính (m & p) của cácclass
trước như sau: 3.2. Điều này sẽexport
m & p củabase class
như m & p củaclass
. -
Mỗi phương thức và thuộc tính của lớp được xuất ra như là một biến
global
dưới dạngobjectName_methodProperty_name
. Bạn có thể khởi tạo các thuộc tính thông qua các tham số, hoặc với một giá trị mặc định, hoặc để nó không bắt buộc. -
Điều này sẽ tìm thấy tất cả các
function
vớiprefix
làBaseClass_ *
và tạo nó như là một biếnglobal
thay thếBaseClass
với tên của đối tượng, giá trị của biến sẽ là một chuỗi vớifunction
lớp cơ sở và tênclass
là tham số đầu tiên đóng vai trò là một tham chiếu Với nó. -
Các
function
của lớp được định nghĩa làBaseClass_methodName
. Tênfunction
có thể chứa dấu gạch dưới,camelCase
được khuyến khích. -
Lấy một tham chiếu đến
base class
(không bắt buộc) và đối tượng, đối số đầu tiên là tên đối tượng. -
Tất nhiên, bạn có thể tạo các đối tượng mới bên trong các
function
của cùng một lớp.
Để sử dụng các class
. Tạo một phần mềm từ đó bạn sẽ sử dụng class
mà bạn đã định nghĩa:
#!/bin/bash
# Import the class definition file.
. vector.sh
function main()
{
# Create the vectors objects. (1)
Vector 'vector1' 1 2 3
Vector 'vector2' 7 5 3
# Show it's properties. (2)
echo "vector1 ($vector1_x, $vector1_y, $vector1_z)"
echo "vector2 ($vector2_x, $vector2_y, $vector2_z)"
# Call to it's methods.
$vector1_show
$vector2_show
$vector1_add vector2
}
main
1.Các đối tượng được khai báo là đối tượng class objectName [arg1 arg2 arg3 ...]
.
2.Bây giờ bạn có thể gọi các function
và thuộc tính như $ objectName_methodsProperty_name [arg1 arg2 arg3 ...]
.
Kết qủa là:
$ ./main.sh
vector1 (1, 2, 3)
vector2 (7, 5, 3)
vector1 (1, 2, 3)
vector2 (7, 5, 3)
vector3 (8, 7, 6)
OOP trong Bash đã được tạo. Thành tựu đạt được: D (OOP in Bash unlocked. Achievement reached )
Cảm ơn và hi vọng bài viết có ích cho công việc của bạn.
All rights reserved