Liên hệProfile
Danh mục

Mục Lục

    Function trong Bash Shell – Hướng dẫn toàn tập về cách sử dụng hàm trong Bash

    Nguyễn Hưng

    Ngày đăng:

    27/02/2026

    Cập nhật lần cuối:

    27/02/2026

    Lượt xem:
    Chia sẻ
    Đánh giá
    5/5 - (1 bình chọn)

    Nguyễn Hưng

    Lượt xem:
    Ngày đăng:

    27/02/2026

    Cập nhật lần cuối:

    27/02/2026

    Mục lục

    Function trong Bash shell là một khối lệnh được đặt tên, dùng để gom nhóm các câu lệnh lại và tái sử dụng nhiều lần trong script thay vì phải viết lặp đi lặp lại. Trong bài viết này, mình sẽ hướng dẫn cách gọi và truyền tham số cho function trong Bash, đồng thời sử dụng các tham số đặc biệt để viết script linh hoạt và dễ bảo trì.

    Những điểm chính

    • Định nghĩa Function trong Bash shell: Hiểu rõ khái niệm function là một khối lệnh được đặt tên, giúp gom nhóm và tái sử dụng mã lệnh.
    • Lợi ích: Nắm rõ các lợi ích chính khi sử dụng Function trong Bash shell như tối ưu hóa script, tuân thủ nguyên tắc DRY và đơn giản hóa việc bảo trì hệ thống lâu dài.
    • Cú pháp khai báo: Thành thạo các cách định nghĩa hàm khác nhau, từ chuẩn POSIX đến cách viết rút gọn trên một dòng lệnh.
    • Cách gọi và quản lý: Biết cách thực thi hàm, kiểm tra mã nguồn của hàm và xóa hàm khỏi bộ nhớ shell một cách chuyên nghiệp.
    • Phạm vi biến: Hiểu sâu về biến toàn cục và cách dùng từ khóa local để tránh xung đột dữ liệu khi viết các script phức tạp.
    • Xử lý tham số: Làm chủ kỹ thuật truyền tham số và sử dụng các biến đặc biệt ($0, $#, $?, $@) để tăng tính linh hoạt cho hàm.
    • Giá trị trả về: Phân biệt được cách trả về mã trạng thái thoát và cách hứng dữ liệu thực tế thông qua stdout và command substitution.
    • Ứng dụng thực tế: Áp dụng hàm vào các kịch bản DevOps thực tế.
    • Giải đáp thắc mắc (FAQ): Có được câu trả lời cho các câu hỏi thực tế về khi nào nên tách logic thành function, cách khai báo và cơ chế trả về dữ liệu trong Bash.

    Function trong Bash shell là gì?

    Function trong Bash shell là một tập hợp các lệnh được nhóm lại dưới một tên cụ thể, cho phép tái sử dụng mã lệnh nhiều lần trong script.​ Khi bạn gọi tên hàm, khối lệnh đó sẽ được thực thi.

    Về bản chất, hàm trong Bash tương tự như:

    • Procedure/Subroutine: Trong các ngôn ngữ lập trình thủ tục.
    • Method: Trong các ngôn ngữ hướng đối tượng (nhưng đơn giản hơn).
    Function trong Bash shell là một tập hợp các lệnh được nhóm lại dưới một tên cụ thể
    Function trong Bash shell là một tập hợp các lệnh được nhóm lại dưới một tên cụ thể

    Những lợi ích khi sử dụng function

    Việc sử dụng function mang lại các lợi ích cốt lõi:

    • Tối ưu và chuẩn hóa mã nguồn: Việc sử dụng hàm giúp loại bỏ sự lặp lại của các đoạn mã xử lý giống nhau, đồng thời đảm bảo tuân thủ nghiêm ngặt nguyên tắc DRY (Don’t Repeat Yourself). Nhờ vậy, thay vì phải sao chép và dán cùng một đoạn logic ở nhiều nơi, bạn chỉ cần định nghĩa logic đó một lần duy nhất trong hàm và gọi lại khi nào cần thiết.
    • Dễ bảo trì và cập nhật: Khi cần thay đổi logic, bạn chỉ cần chỉnh sửa tại một nơi duy nhất (trong định nghĩa hàm) thay vì phải tìm và sửa hàng chục vị trí trong script.
    • Cải thiện tính đọc hiểu: Việc chia nhỏ script thành các hàm có tên gọi gợi nhớ giúp người khác (hoặc chính bạn sau này) dễ dàng hiểu được mục đích của từng khối lệnh.
    • Quản lý phạm vi biến: Hàm cho phép sử dụng biến cục bộ, giúp tránh xung đột dữ liệu với các phần khác của script.
    • Tối ưu hóa cấu trúc: Giúp chia nhỏ các bài toán phức tạp thành các module con đơn giản, dễ kiểm soát và gỡ lỗi.
    Những lợi ích khi sử dụng function
    Những lợi ích khi sử dụng function

    Trong Bash, có hai cách chính để định nghĩa một hàm và một cách viết rút gọn như sau:

    Cách 1: Sử dụng dấu ngoặc đơn ()

    Dùng dấu ngoặc đơn là cách khai báo phổ biến và gọn gàng hơn, thường được các lập trình viên ưu tiên sử dụng. Đây là cách viết tuân thủ chuẩn POSIX, đảm bảo tính di động cao nhất giữa các loại shell khác nhau. Dưới đây là cú pháp lệnh:

    ten_ham() {
        # Các câu lệnh cần thực thi
        echo "Đây là hàm được khai báo bằng dấu ngoặc đơn"
    }
    Sử dụng dấu ngoặc đơn 
    Sử dụng dấu ngoặc đơn 

    Cách 2: Sử dụng từ khóa function

    Đây là cách khai báo tường minh, sử dụng từ khóa function trước tên hàm với cú pháp thực hiện như sau:

    function ten_ham {
        # Các câu lệnh cần thực thi
        echo "Đây là hàm được khai báo bằng từ khóa function"
    }
    Sử dụng từ khóa function
    Sử dụng từ khóa function

    iconLưu ý

    Cách này rõ ràng nhưng không tuân thủ hoàn toàn chuẩn POSIX (có thể không chạy trên một số shell cũ hoặc khác Bash).

    Cách 3: Viết hàm trên một dòng

    Cách này thích hợp cho các hàm ngắn gọn dùng trong terminal. Lưu ý quan trọng: Bạn bắt buộc phải có dấu chấm phẩy ; sau lệnh cuối cùng trước khi đóng ngoặc nhọn.

    Ví dụ:

    in_ngay() { date; }

    Cách thực thi hàm trong Script và Terminal

    Để gọi hàm, bạn chỉ cần gõ tên hàm giống như một câu lệnh thông thường (không cần dấu ngoặc đơn () phía sau).

    Nguyên tắc: Hàm phải được định nghĩa/khai báo trước khi được gọi trong script.

    Ví dụ:

    # Định nghĩa
    
    xin_chao() { echo "Hello World"; }
    
    # Gọi hàm
    
    xin_chao

    Kiểm tra và xem nội dung hàm

    Nếu bạn muốn kiểm tra xem một hàm đã được định nghĩa chưa hoặc xem nội dung của hàm trong terminal thì hãy gõ các lệnh sau:

    • declare -F: Hiển thị danh sách tên các hàm đã định nghĩa.
    • declare -f ten_ham: Hiển thị toàn bộ mã nguồn của hàm đó.

    Cách xóa hàm

    Để xóa một hàm khỏi bộ nhớ của shell hiện tại, bạn sử dụng lệnh:

    unset ten_ham

    iconLưu ý

    Nếu trùng tên với biến thì bạn dùng lệnh unset -f ten_ham để chỉ định xóa hàm.

    Biến toàn cục

    Theo mặc định, tất cả biến trong Bash đều là toàn cục, ngay cả khi chúng được khai báo bên trong hàm. Điều này có nghĩa là biến có thể được truy cập và thay đổi giá trị từ bất kỳ đâu trong script. Tuy nhiên biến toàn cục dễ gây ra lỗi “side effect” không mong muốn nếu các hàm khác nhau vô tình thay đổi cùng một biến.

    Biến cục bộ 

    Để giới hạn phạm vi biến chỉ tồn tại trong hàm, bạn hãy sử dụng từ khóa local. Điều này sẽ giúp tránh xung đột tên biến (Shadowing/Overriding) với biến toàn cục hoặc biến của hàm khác.

    Lời khuyên: Bạn nên luôn sử dụng local cho các biến tạm trong hàm.

    Ví dụ:

    name="Global Name"
    
    test_scope() {
        local name="Local Name"
        echo "Trong hàm: $name"
    }
    
    test_scope
    echo "Ngoài hàm: $name"
    
    # Kết quả:
    # Trong hàm: Local Name
    # Ngoài hàm: Global Name

    Cách xử lý tham số trong hàm

    Khác với các ngôn ngữ lập trình như Python hay C++, trong Bash, bạn không khai báo tham số bên trong dấu ngoặc (). Thay vào đó, tham số được truyền vào khi gọi hàm và được truy xuất bên trong hàm thông qua các biến vị trí.

    1. Cách truyền và nhận tham số

    • Truyền tham số: Viết các giá trị ngay sau tên hàm, cách nhau bởi khoảng trắng.
    • Nhận tham số: Sử dụng $1 cho tham số đầu tiên, $2 cho tham số thứ hai,…

    Ví dụ minh họa:

    Truyền và nhận tham số
    Truyền và nhận tham số

    2. Các tham số đặc biệt

    Bên cạnh các biến vị trí $1, $2…, Bash cung cấp các biến đặc biệt giúp bạn kiểm soát luồng xử lý của hàm tốt hơn:

    Tham sốÝ nghĩaVí dụ sử dụng
    $0Tên của file script đang chạy.echo "Đang chạy script: $0"
    $#Tổng số lượng đối số đã được truyền vào hàm.if [ $# -eq 0 ]; then echo "Thiếu tham số"; fi
    $?Trạng thái thoát của lệnh hoặc hàm vừa thực thi.0 là thành công, khác 0 là lỗi.
    $@Đại diện cho tất cả các tham số truyền vào.for arg in "$@"; do ... done

     Để tra cứu nhanh các thông tin kỹ thuật về hàm trong terminal, bạn có thể sử dụng lệnh:

    help function

    Khác với các ngôn ngữ lập trình như Python hay JavaScript, Bash xử lý giá trị trả về theo cách riêng biệt.

    Trả về trạng thái thoát 

    Hàm sử dụng từ khóa return để trả về trạng thái thành công hoặc thất bại. Trong đó, giá trị trả về sẽ là số nguyên từ 0 đến 255.

    • 0: Thành công.
    • Khác 0 (1-255): Thất bại/Lỗi.

    Bạn có thể kiểm tra giá trị này ngay sau khi gọi hàm bằng biến $?.

    Trả về dữ liệu thực tế

    Bash không hỗ trợ return “chuỗi dữ liệu”. Để lấy dữ liệu đầu ra từ hàm, bạn có 2 giải pháp:

    • Gán vào biến toàn cục: Cách này không khuyến khích vì khó debug.
    • Sử dụng echo và Command Substitution: Cách này sẽ in kết quả ra stdout và hứng lấy giá trị khi gọi hàm.

    Ví dụ:

    lay_ngay_gio() {
        local now=$(date +%F)
        echo "$now"  # In ra stdout thay vì return
    }
    
    # Hứng dữ liệu vào biến
    current_date=$(lay_ngay_gio)
    echo "Hôm nay là: $current_date"

    Script kiểm tra tài nguyên hệ thống

    Sau đây là một script ví dụ để tự động kiểm tra dung lượng ổ đĩa và cảnh báo.

    check_disk_usage() {
        local threshold=90
        local usage=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
    
        if [ "$usage" -gt "$threshold" ]; then
            echo "CẢNH BÁO: Ổ cứng đầy ($usage%)"
            return 1
        else
            echo "OK: Ổ cứng ổn định ($usage%)"
            return 0
        fi
    }

    Tổ chức Script theo dạng Module

    Bạn có thể tách các hàm ra một file riêng (ví dụ utils.sh) và import vào script chính để thu gọn code thông qua lệnh source hoặc dấu chấm .:

    # Trong file main.sh
    source ./utils.sh
    # Hoặc
    . ./utils.sh
    
    # Sau đó gọi hàm từ utils.sh bình thường

    Ghi đè lệnh hệ thống

    Bạn có thể tạo wrapper để thêm chức năng cho lệnh chuẩn. Ví dụ: Tự động ls sau khi cd.

    cd() {
        builtin cd "$@" && ls  # Dùng builtin để gọi lệnh cd gốc
    }

    Câu hỏi thường gặp

    Khi nào nên tách logic thành function thay vì viết thẳng trong script?

    Bạn nên tách thành function khi một đoạn logic được dùng từ 2 lần trở lên hoặc khi đoạn xử lý đủ dài và khó hiểu khiến cho phần main của script trở nên rối.​ Ngoài ra, bạn nên tạo function cho từng nhiệm vụ rõ ràng để dễ test độc lập, dễ debug và có thể tái sử dụng ở script khác.​

    Nên dùng kiểu khai báo function name {} hay name() {}?

    Cả hai đều hợp lệ trong Bash, nhưng name() {} thường được khuyến nghị vì ngắn gọn, phổ biến và tương thích tốt hơn với nhiều shell khác.​

    Có nên để function trả về dữ liệu bằng return trong Bash?

    return trong Bash chỉ trả về mã trạng thái từ 0–255 chứ không phải giá trị kiểu chuỗi hay số như trong nhiều ngôn ngữ khác.​
    Để trả dữ liệu, thông thường function sẽ in ra stdout rồi bên ngoài bắt lại bằng command substitution result="$(my_func …)", còn return chỉ dùng để báo thành công/thất bại hoặc các mã lỗi đặc biệt.​

    Function trong Bash giúp gom nhóm các lệnh thành khối logic có tên, tái sử dụng nhiều lần, từ đó loại bỏ lặp mã và tuân thủ nguyên tắc DRY trong script.​ Khi kết hợp function với cơ chế truyền tham số, bạn có thể xây dựng script linh hoạt, dễ kiểm soát lỗi và rất thuận tiện cho việc mở rộng, bảo trì về sau.​

    5/5 - (1 bình chọn)
    Nguyễn Hưng
    Tôi là Nguyễn Hưng hay còn được biết đến với nickname là Bo, chuyên gia về hệ thống, mạng và bảo mật. Tôi là Co-Founder của Vietnix và Co-Founder của dự án Chống Lừa Đảo.
    0 0 đánh giá
    Đánh giá bài viết
    Theo dõi
    Thông báo của
    guest
    0 Góp ý
    Cũ nhất
    Mới nhất Được bỏ phiếu nhiều nhất
    Phản hồi nội tuyến
    Xem tất cả bình luận

    BÀI VIẾT LIÊN QUAN

    Cách dùng dmidecode trên Linux để xem thông tin phần cứng chính xác và nhanh chóng
    Cách dùng dmidecode trên Linux để xem thông tin phần cứng chính xác và nhanh chóng

    dmidecode là một công cụ dòng lệnh trên Linux dùng để đọc và hiển thị thông tin phần cứng máy tính từ bảng DMI hoặc SMBIOS cung cấp bởi BIOS, giúp kiểm tra chi tiết như nhà sản xuất, model, số serial, BIOS, CPU, RAM mà không cần mở máy. Trong bài viết này, mình…

    27/02/2026

    Lệnh partx Linux là gì? 7 ví dụ ứng dụng thực tế của lệnh partx
    Lệnh partx Linux là gì? 7 ví dụ ứng dụng thực tế của lệnh partx

    Lệnh partx Linux là một công cụ dòng lệnh thuộc gói util-linux, được sử dụng để thêm, xóa hoặc liệt kê các phân vùng của thiết bị đĩa vào bảng phân vùng của hệ thống mà không cần khởi động lại hoặc gắn lại thiết bị. Trong bài viết này, mình sẽ hướng dẫn bạn…

    27/02/2026

    Hướng dẫn 7 cách kiểm tra CPU trên Linux chính xác và nhanh chóng
    Hướng dẫn 7 cách kiểm tra CPU trên Linux chính xác và nhanh chóng

    Trong môi trường quản trị Linux, việc kiểm tra tốc độ xung nhịp CPU là một thao tác cần thiết giúp người dùng đánh giá khả năng chịu tải, phát hiện các điểm nghẽn hiệu suất  và hỗ trợ tối ưu trong quá trình tối ưu hóa hoặc khắc phục sự cố phần cứng. Trong…

    27/02/2026

    Hướng dẫn xóa bộ nhớ Cache, bộ đệm và Swap trong Linux nhanh chóng, chi tiết
    Hướng dẫn xóa bộ nhớ Cache, bộ đệm và Swap trong Linux nhanh chóng, chi tiết

    Trong Linux, bộ nhớ cache là nơi lưu trữ tạm thời dữ liệu và các file đã truy cập gần đây để giảm thời gian truy xuất ở lần tiếp theo. Tuy nhiên, theo thời gian, bộ nhớ cache có thể chiếm dụng quá nhiều RAM, đặc biệt trên các máy chủ có uptime dài…

    27/02/2026

    linux

    lenh

    text