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 - (2 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 - (2 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

    smartctl là gì? Cách sử dụng smartctl trong Linux để kiểm tra sức khỏe ổ cứng
    smartctl là gì? Cách sử dụng smartctl trong Linux để kiểm tra sức khỏe ổ cứng

    smartctl là một tiện ích dòng lệnh giúp quản lý và giám sát hệ thống S.M.A.R.T., từ đó theo dõi chi tiết sức khỏe ổ cứng HDD/SSD trong môi trường máy chủ lẫn máy trạm cá nhân. Trong bài viết này, bạn sẽ tìm hiểu cách cài đặt, sử dụng các lệnh smartctl quan trọng…

    14/04/2026

    cryptsetup là gì? Cách mã hóa phân vùng với cryptsetup (LUKS) trên Linux
    cryptsetup là gì? Cách mã hóa phân vùng với cryptsetup (LUKS) trên Linux

    cryptsetup là tiện ích dòng lệnh nguồn mở trong Linux dùng để quản lý mã hóa đĩa dựa trên dm-crypt và chuẩn LUKS, hỗ trợ tạo volume an toàn với nhiều khóa và tương thích cao. Bài viết này hướng dẫn toàn diện về cryptsetup từ cài đặt, quy trình mã hóa, quản lý key…

    14/04/2026

    Aureport là gì? Hướng dẫn sử dụng lệnh aureport trên Linux
    Aureport là gì? Hướng dẫn sử dụng lệnh aureport trên Linux

    Aureport là công cụ dòng lệnh mạnh mẽ trong hệ thống auditd Linux, chuyên tạo báo cáo thống kê tóm tắt từ các tệp nhật ký kiểm toán. Bài viết này sẽ hướng dẫn chi tiết cách sử dụng aureport để giám sát bảo mật và phân tích hoạt động hệ thống hiệu quả. Những…

    09/04/2026

    Auditctl là gì? Hướng dẫn sử dụng lệnh auditctl trong Linux để quản lý hệ thống Audit
    Auditctl là gì? Hướng dẫn sử dụng lệnh auditctl trong Linux để quản lý hệ thống Audit

    Auditctl là công cụ dòng lệnh quan trọng trong Linux, cho phép quản trị viên thiết lập và quản lý các quy tắc giám sát (audit) trực tiếp trên kernel. Thông qua auditctl, bạn có thể theo dõi chi tiết các hoạt động như truy cập file, thực thi syscall hay hành vi người dùng…

    09/04/2026

    linux

    lenh

    text