Việc gán output của lệnh vào một biến giúp bạn lưu trữ kết quả đó trong biến và tái sử dụng linh hoạt trong suốt script, từ kiểm tra điều kiện, xử lý chuỗi cho đến log hoặc tự động hóa các tác vụ phức tạp. Trong bài viết này, mình sẽ hướng dẫn bạn cách gán output của Linux vào biến một cách chuẩn xác nhất, kèm các ví dụ thực tế để bạn có thể áp dụng ngay trong Shell Script.
Những điểm chính
- Quan điểm của mình: Việc hiểu và lựa chọn đúng cú pháp gán biến không chỉ giúp mã nguồn của bạn gọn gàng, dễ đọc hơn mà còn đảm bảo tính tương thích cao khi script được chạy trên nhiều bản phân phối Linux khác nhau.
- Lợi ích khi gán output: Hiểu rõ các lợi ích chính như tái sử dụng dữ liệu, tối ưu hiệu năng và tăng tính dễ đọc cho script của bạn.
- Cách gán output của lệnh: Nắm vững hai phương pháp gán output vào biến bằng cú pháp
$(...)và dấu ngoặc ngược``. - Các ví dụ ứng dụng thực tế: Thành thạo cách áp dụng kỹ thuật này vào các tình huống thực tế như lưu thông tin người dùng và đếm số lượng file.
- Những lưu ý khi gán output: Biết được các lưu ý quan trọng để tránh các lỗi phổ biến như mất dòng cuối, không bắt được lỗi và rủi ro đầy bộ nhớ.
- Giải đáp thắc mắc (FAQ): Có được câu trả lời cho các vấn đề nâng cao như khi nào nên dùng dấu nháy kép, khi nào nên pipe trực tiếp và cách xử lý lỗi.
Lợi ích khi gán output của Linux cho một biến
Khi làm việc với Bash Shell hay các trình bao khác trong Linux, việc gán output vào biến mang lại những lợi ích vô cùng thiết thực:
- Tái sử dụng dữ liệu: Bạn chỉ cần thực thi lệnh một lần duy nhất và có thể sử dụng kết quả đó nhiều lần ở các đoạn code khác nhau trong script, giúp tránh việc lặp lại mã nguồn.
- Tối ưu hiệu năng: Đối với các lệnh tốn nhiều tài nguyên hoặc thời gian xử lý như find trên ổ cứng lớn hoặc gọi API qua mạng, việc lưu vào biến giúp hệ thống không phải tốn CPU/RAM để chạy lại lệnh đó mỗi khi cần lấy dữ liệu.
- Đảm bảo tính nhất quán: Giúp đóng băng dữ liệu tại thời điểm thực thi. Ví dụ: nếu bạn dùng lệnh date hoặc uptime trực tiếp hai lần ở hai dòng khác nhau, kết quả sẽ bị lệch nhau vài giây. Khi đó việc lưu vào biến đảm bảo giá trị thời gian là đồng nhất trong toàn bộ quá trình xử lý.
- Dễ dàng thao tác và xử lý: Khi dữ liệu nằm trong biến, bạn có thể dễ dàng áp dụng các kỹ thuật cắt chuỗi, so sánh trong câu lệnh điều kiện (if/else) hoặc thực hiện các phép toán số học.
- Tăng tính dễ đọc: Thay vì viết một dòng lệnh dài và phức tạp lặp đi lặp lại, bạn gán nó vào một biến có tên gợi nhớ sẽ giúp code trở nên gọn gàng và dễ bảo trì hơn.

Cách gán output của Linux cho một biến
Bạn có thể sử dụng tính năng command substitution (thay thế lệnh) trong shell để gán kết quả của một lệnh vào biến với hai cách phổ biến sau:
Cách 1: Sử dụng cú pháp $()
Đây là phương pháp tiêu chuẩn POSIX hiện đại. Các chuyên gia hệ thống luôn khuyến nghị sử dụng cú pháp này nhờ tính rõ ràng và khả năng hỗ trợ lồng nhiều lệnh vào nhau một cách dễ dàng.
Cú pháp lệnh như sau:
ten_bien=$(lenh)Ví dụ: Để lấy danh sách chi tiết các file trong thư mục hiện tại và gán vào biến output, bạn hãy mở terminal và nhập lệnh sau:
output=$(ls -l)Khi đó, kết quả sẽ hiển thị như sau:

Cách 2: Sử dụng dấu ngoặc ngược ` `
Đây là phương pháp cũ nhưng vẫn được hỗ trợ để tương thích ngược với các shell đời cũ như sh. Tuy nhiên bạn cần lưu ý cú pháp này mang lại một số bất tiện khi đọc code.
Cú pháp lệnh như sau:
ten_bien=`lenh`Ví dụ:
output=`ls -l`Khi đó, màn hình sẽ hiển thị kết quả như sau:

Lỗi thường gặp: Ký tự ngoặc ngược (`) trên bàn phím rất dễ bị nhầm lẫn với dấu nháy đơn (‘). Nếu bạn vô tình gõ dấu nháy đơn, hệ thống Linux sẽ coi đoạn nội dung bên trong là một chuỗi văn bản (string) bình thường thay vì thực thi lệnh, dẫn đến việc biến không lưu được dữ liệu mong muốn.
Để bạn dễ dàng hình dung sự khác biệt, dưới đây là bảng so sánh chi tiết giữa hai phương pháp:
| Tiêu chí | Cú pháp $() | Cú pháp ngoặc ngược |
|---|---|---|
| Tính dễ đọc | Cao, dễ dàng phân biệt bằng mắt thường. | Thấp, dễ nhầm lẫn với dấu nháy đơn (‘). |
| Khả năng lồng nhau | Rất dễ. Cú pháp: a=$(echo $(ls)) | Phức tạp, phải dùng dấu \ để thoát ký tự: a=\echo `ls``` |
| Độ phổ biến | Chuẩn POSIX hiện đại, được dùng rộng rãi. | Chuẩn cũ, đang dần ít được sử dụng trong script mới. |
Lựa chọn của chuyên gia: Mặc dù cả hai đều mang lại kết quả như nhau, nhưng nếu bạn thường xuyên viết các shell script phức tạp và yêu cầu tính bảo trì cao, mình khuyên bạn chỉ nên sử dụng cú pháp $(). Điều này giúp hạn chế lỗi cú pháp, đặc biệt là khi bạn phải lồng nhiều lệnh ghép vào bên trong một biến.
Các ví dụ ứng dụng thực tế trong quản trị hệ thống
Lưu trữ thông tin người dùng hệ thống
Trong trường hợp này, bạn sử dụng lệnh who để lấy danh sách người dùng đang đăng nhập và gán vào biến CURRENT_USERS.
Cú pháp thực hiện như sau:
CURRENT_USERS=$(who)Kết quả hiển thị sau khi chạy lệnh như sau:

Sau đó, bạn sử dụng lệnh echo kết hợp tham số -e (hỗ trợ đọc ký tự xuống dòng \n) để in thông báo ra màn hình:
echo -e "Các người dùng hiện đang đăng nhập trên hệ thống là:\n\n $CURRENT_USERS"Kết quả hiển thị như sau:

Mẹo tối ưu: Để tiết kiệm bộ nhớ và rút ngắn code, nếu không cần dùng lại biến CURRENT_USERS cho các bước sau thì bạn có thể gọi thẳng lệnh bên trong echo:
echo -e "Các người dùng hiện đang đăng nhập trên hệ thống là:\n\n $(who)"Kết quả trả ra như sau:

Đếm số lượng file
Để đếm đếm số lượng file trong thư mục hiện tại, bạn có thể kết hợp lệnh find và wc thông qua pipe |, sau đó gán kết quả cuối cùng vào biến. Lệnh thực thi như sau:
FILES=`sudo find . -type f -print | wc -l`
Trong đó: Lệnh find . -type f -print thực hiện quét và tìm tất cả các tệp tin trong thư mục hiện hành. Sau đó, kết quả được đẩy qua ống dẫn (pipe |) cho lệnh wc -l để đếm tổng số dòng (tương ứng với số tệp).
Sau khi có dữ liệu, bạn tiến hành in kết quả ra màn hình:
echo "Có tất cả $FILES tệp tin trong thư mục hiện tại."
Những lưu ý khi gán output của Linux cho một biến
Để script của bạn hoạt động ổn định và không phát sinh lỗi tiềm ẩn, hãy ghi nhớ các lưu ý sau:
- Hiện tượng mất dòng cuối: Cơ chế này mặc định tự động loại bỏ các ký tự xuống dòng
(\n)ở cuối kết quả nên có thể gây sai lệch định dạng. - Không bắt được thông báo lỗi: Biến chỉ lưu dữ liệu đầu ra chuẩn nên các thông báo lỗi sẽ bị in thẳng ra màn hình trừ khi bạn điều hướng bằng
2>&1. - Quy tắc ngoặc kép: Bạn nên sử dụng dấu ngoặc kép khi gọi biến để bảo toàn khoảng trắng và tránh lỗi tách từ.
- Rủi ro đầy bộ nhớ: Bạn nên tránh gán nội dung quá lớn vào biến vì dữ liệu được lưu trên RAM vì điều này rất dễ gây treo hệ thống.

Câu hỏi thường gặp
Có nên dùng dấu nháy kép quanh $(…) khi gán biến không?
Bạn nên viết dạng var="$(command)" để giữ nguyên khoảng trắng và xuống dòng trong output, tránh bị shell tự động tách thành nhiều từ khi xử lý sau này. Ngoài ra, bạn chỉ nên bỏ nháy kép khi bạn muốn tách output thành nhiều từ/argument cho lệnh tiếp theo.
Khi nào không nên gán output vào biến mà nên pipe trực tiếp?
Bạn không nên gán nếu output quá lớn vì sẽ tốn RAM và làm script khó đọc hơn. Những trường hợp chỉ xử lý một lần theo pipeline thì pipe trực tiếp sẽ gọn, rõ và hiệu quả hơn là gán cả chuỗi đó vào biến rồi mới xử lý.
Làm sao xử lý lỗi khi lệnh bên trong $(…) thất bại?
Bạn có thể kiểm tra mã thoát của lệnh bằng cách gán kết quả rồi dùng $? hoặc dùng set -e/set -o pipefail trong script để script dừng khi command substitution lỗi. Ngoài ra, bạn nên kiểm tra biến sau khi gán trước khi dùng để tránh lỗi dây chuyền ở các bước sau.
Kỹ thuật gán output của lệnh vào biến giúp script Linux trở nên linh hoạt, dễ đọc và dễ bảo trì hơn, đồng thời tối ưu hiệu năng nhờ hạn chế chạy lệnh lặp lại không cần thiết. Bạn hãy ưu tiên cú pháp $(…), luôn trích xuất vào biến có ý nghĩa và trích dẫn đúng cách để tận dụng tối đa sức mạnh của command substitution trong các trường hợp sử dụng thực tế của mình.




