Câu 1Cách viết nào tham chiếu tham số thứ nhất bên trong một hàm shell?
Hàm — Gom đoạn xử lý lặp lại vào một chỗ
Bài viết này là một phần của Khóa học Linux, giúp bạn thành thạo từ đầu những kỹ năng Linux thực tiễn, từ các lệnh cơ bản đến lập trình shell script.
Định nghĩa logic bằng name() { ... }, nhận tham số qua $1, giữ biến cục bộ trong hàm bằng local, và rẽ nhánh theo thành công bằng return và $? để tái sử dụng cùng một logic kiểm tra — được minh họa và thực hành trong terminal trên trình duyệt.
Đặt tên cho một khối logic — định nghĩa hàm và tham số
Thay vì viết cùng một logic lặp đi lặp lại, bạn có thể gói nó vào một hàm và gọi nó bằng tên.
Định nghĩa một hàm bằng name() { ... }, và đặt phần thân giữa { và }.
Sau khi định nghĩa, chỉ cần viết name để chạy logic đó.
Cách này chia một script dài thành các đơn vị có ý nghĩa, và bạn chỉ phải sửa ở một chỗ.
Để truyền giá trị vào một hàm, hãy thêm tham số sau tên khi bạn gọi nó, ví dụ name foo bar.
Bên trong hàm, $1 là tham số thứ nhất và $2 là tham số thứ hai (cùng cách viết với các tham số vị trí của chính script).
Bao một tham số trong dấu nháy kép như "$1", và ngay cả một giá trị có khoảng trắng cũng được xem như một tham số duy nhất.
greet() { # định nghĩa một hàm
echo "hello, $1"
}
greet alice # hello, alice
greet bob # hello, bob
greet alice bob đi vào $1 và $2, và phần thân hàm dùng chúng để làm việc.| Cú pháp | Ý nghĩa | Ví dụ |
|---|---|---|
name() { … } | Định nghĩa một hàm | greet() { echo "hi $1"; } |
name args | Gọi một hàm | greet alice |
$1 | Tham chiếu tham số thứ nhất bên trong hàm | echo "name=$1" |
$2 | Tham chiếu tham số thứ hai bên trong hàm | echo "port=$2" |
Biến chỉ tồn tại bên trong một hàm — local
Khi bạn khai báo local v=... bên trong một hàm, biến đó chỉ có hiệu lực bên trong hàm và biến mất khi hàm kết thúc.
Không có local, bạn cũng ghi đè lên một biến cùng tên ở bên ngoài hàm, điều này gây ra những tác dụng phụ không mong muốn.
Để tái sử dụng một hàm an toàn như một thành phần, hãy làm cho các biến làm việc mà nó dùng bên trong thành local.
msg="outer"
show() {
local msg="inner" # biến chỉ tồn tại trong hàm
echo "in func: $msg"
}
show # in func: inner
echo "outside: $msg" # outside: outer (bên ngoài không đổi)
local chỉ có hiệu lực bên trong hàm. Dù cùng tên, giá trị bên ngoài cũng không thay đổi.| Cú pháp | Ý nghĩa | Ví dụ |
|---|---|---|
local v=… | Tạo một biến chỉ có hiệu lực bên trong hàm | local step=1 |
v=… | Một biến có hiệu lực trên toàn bộ script | status=ready |
Trả về thành công hay thất bại — return và $?
Một hàm có thể trả về một mã thoát bằng return N.
Theo quy ước 0 nghĩa là thành công và bất kỳ giá trị nào khác 0 nghĩa là thất bại, và ngay sau khi gọi nó bạn có thể kiểm tra giá trị đó bằng $?.
Rẽ nhánh trực tiếp theo thành công của một hàm như if check "$x"; then ... giúp luồng kiểm tra và xử lý dễ đọc hơn.
is_num() {
case "$1" in
*[!0-9]*|"") return 1 ;; # thất bại nếu chứa ký tự không phải số hoặc rỗng
*) return 0 ;;
esac
}
is_num 12; echo "12 -> $?" # 12 -> 0
is_num abc; echo "abc -> $?" # abc -> 1
return đi vào $?, và if rẽ nhánh xem 0 là thành công và khác không là thất bại.| Cú pháp | Ý nghĩa | Ví dụ |
|---|---|---|
return 0 | Thoát hàm với kết quả thành công | is_num 12; # success |
return 1 | Thoát hàm với kết quả thất bại | is_num abc; # failure |
$? | Kiểm tra giá trị trả về của hàm trước đó | is_num 12; echo $? |
if name x; then … | Rẽ nhánh trực tiếp theo giá trị trả về | if is_num "$v"; then …; fi |
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Phạm vi của một biến được khai báo bằng local là gì?
Câu 3Cách nào kiểm tra giá trị trả về của hàm gần nhất?