Linux, kế thừa triết lý thiết kế mạnh mẽ từ Unix, nổi tiếng với khả năng cho phép các chương trình giao tiếp thông qua văn bản, dễ dàng kết hợp chúng thông qua các đường ống (pipelines), và mỗi chương trình thường chỉ làm một việc thật tốt. Tuy nhiên, ngoài những nguyên tắc cốt lõi này, các chương trình trong Linux còn có thể hoạt động rất khác nhau và thể hiện nhiều hành vi đa dạng. Việc hiểu rõ các loại chương trình phổ biến này là chìa khóa để khai thác tối đa sức mạnh của hệ điều hành mã nguồn mở này, từ các tác vụ quản trị hệ thống phức tạp đến việc phát triển ứng dụng hàng ngày.
Các Tiến Trình Nền (Background Processes)
Một hệ điều hành đa nhiệm như Linux có thể chạy nhiều chương trình cùng lúc. Những chương trình hoạt động mà không cần người dùng trực tiếp điều khiển được gọi là các tiến trình nền. Về cơ bản, chỉ có một loại tiến trình nền chính, thường được biết đến với tên gọi “daemon”.
Daemon
Thuật ngữ “daemon” nghe có vẻ lạ lẫm, nhưng nó chỉ đơn giản có nghĩa là “tiến trình chạy nền”. Một daemon thường sử dụng các kỹ thuật đặc biệt để tự duy trì hoạt động, bất kể điều gì khác xảy ra trên hệ thống. Ví dụ, nó có thể tự phân nhánh (fork) một bản sao của chính nó để chạy độc lập với shell mà người dùng đang sử dụng. Các dịch vụ như inetd
hoặc systemd
có thể thực hiện công việc này thay mặt một chương trình, và bản thân chúng cũng là các daemon.
Các daemon thường có tên kết thúc bằng chữ “d”, ví dụ như httpd
(máy chủ web Apache), inetd
(daemon dịch vụ internet), và systemd
. Nếu một chương trình bên ngoài—hoặc người dùng—cần giao tiếp với một daemon, nó thường thực hiện bằng cách gửi một tín hiệu (signal) để chỉ thị daemon khởi động lại hoặc tải lại cấu hình của nó. Bạn có thể sử dụng công cụ ps
để khám phá những daemon nào đang chạy trên hệ thống của mình.
Giao Diện Dòng Lệnh (Command Line Interface – CLI)
Hầu hết các chương trình Linux đều có giao diện dòng lệnh, nghĩa là bạn sử dụng chúng bằng cách gõ các lệnh văn bản. Đây là những chương trình terminal phổ biến nhất và thường dễ sử dụng nhất. Những chương trình này thường khởi động, chạy nhanh chóng, sau đó dừng lại khi hoàn thành công việc.
Cantrip
Loại chương trình đơn giản nhất—không chính thức được gọi là “cantrip”—chỉ đơn thuần thực hiện hành động mà không cần đầu vào hay tạo ra đầu ra. Các chương trình này thường hoạt động trên tệp hoặc thực hiện các tác vụ quản trị hệ thống liên quan. Chương trình rm
, dùng để xóa một tệp, là một ví dụ điển hình:
rm myfile.txt
Nếu tệp tồn tại, rm
sẽ xóa nó và terminal của bạn sẽ hiển thị dấu nhắc lệnh trên dòng tiếp theo, chờ đợi chương trình hoặc lệnh kế tiếp:
Ảnh minh họa lệnh rm trong Linux không tạo ra bất kỳ đầu ra nào khi xóa tập tin thành công.
Lệnh rm
có một số tùy chọn để kiểm soát cách nó chạy, nhưng sự đơn giản của nó nằm ở việc thiếu vắng đầu vào và đầu ra trực tiếp.
Filter (Bộ Lọc)
Nhiều chương trình Linux hoàn toàn ngược lại: chúng yêu cầu đầu vào và tạo ra đầu ra. Thông thường, các chương trình này sửa đổi đầu vào của chúng theo một cách nào đó, và có rất nhiều chương trình loại này: cut
, head
, sort
, uniq
, v.v.
Lệnh grep
thể hiện ý nghĩa của bộ lọc đặc biệt rõ ràng: nó quét từng dòng đầu vào, tái tạo nó dưới dạng đầu ra nếu nó thỏa mãn một điều kiện nhất định. Trong trường hợp của grep
, điều kiện là một biểu thức chính quy (regular expression) khớp với một mẫu văn bản cụ thể.
Các bộ lọc rất xuất sắc trong việc thao tác dữ liệu và thường được sử dụng trong các đường ống (pipelines) để nối nhiều lệnh lại với nhau nhằm thực hiện một tác vụ phức tạp. Bạn thậm chí có thể kết hợp các công cụ này để xây dựng một cơ sở dữ liệu sơ khai.
Sink (Nơi Chứa/Đích)
Ngược lại với bộ lọc, có rất ít chương trình dạng sink. Loại chương trình này nhận đầu vào, nhưng không tạo ra đầu ra—ít nhất là không phải đầu ra hiển thị trên màn hình terminal của bạn. Một ví dụ là lpr
, máy in dòng, dùng để in một tệp hoặc đầu vào tiêu chuẩn ra giấy.
Các chương trình sink thường xuất ra các phương tiện khác ngoài màn hình, như chương trình espeak
chuyển đổi văn bản thành giọng nói.
Source (Nguồn)
Ngược lại với sink là “source” (nguồn), một chương trình tạo ra đầu ra mà không cần xử lý bất kỳ đầu vào nào. Các chương trình nguồn lấy dữ liệu của chúng từ nơi khác: môi trường hệ thống hoặc một tệp được chỉ định làm đối số, chẳng hạn.
Chương trình ls
sử dụng nhiều phương pháp khác nhau để liệt kê tệp, nhưng nó không bao giờ xử lý đầu vào tiêu chuẩn. Trong trường hợp đơn giản nhất, ls
thậm chí không cần bất kỳ đối số nào:
ls
Theo mặc định, ls
hoạt động trên thư mục hiện tại, in ra nội dung của nó. Bạn có thể hiển thị chi tiết của một thư mục, tệp hoặc tập hợp các tệp khác bằng cách truyền các đối số dòng lệnh:
ls /tmp
ls /etc/passwd
ls ~/.*
Compiler (Trình Biên Dịch)
Trình biên dịch là loại chương trình CLI phức tạp nhất, thường được dành cho mục đích lập trình. Một trình biên dịch sẽ chạy như bất kỳ chương trình nào khác, nhưng có thể mất nhiều thời gian hơn để hoàn thành vì công việc của nó khá phức tạp.
Tên của chúng thường kết thúc bằng chữ “c” cho “compiler”: cc
, javac
, hoặc rustc
. Một trình biên dịch giống một chút như cantrip, nhưng nó luôn làm việc với các tệp, chuyển đổi một loại dữ liệu sang một loại khác.
Trình biên dịch C, cc
, thể hiện hành vi điển hình của một trình biên dịch:
cc file1.c file2.c -o program
Lệnh này chạy trình biên dịch với hai tệp—file1.c
và file2.c
—tạo ra một tệp thứ ba có tên program
. Ở đây, đối số “-o” viết tắt của “output file” (tệp đầu ra).
Điều quan trọng cần lưu ý là trình biên dịch có thể truy xuất các tệp bổ sung, tùy thuộc vào tác vụ hoặc ngôn ngữ cơ bản. Một chương trình C như file1.c
có thể bao gồm một tệp tiêu đề (ví dụ: file1.h
) mà trình biên dịch sẽ định vị và sử dụng để tạo chương trình cuối cùng, mặc dù nó không được đặt tên rõ ràng khi bạn chạy lệnh. Điều này là một phần làm cho trình biên dịch trở nên phức tạp: chúng có thể thực hiện nhiều việc “ngầm” mà không cần được chỉ dẫn trực tiếp.
Các Chương Trình Tương Tác (Interactive Programs)
Các chương trình đã đề cập trước đó đều chạy theo kiểu không tương tác. Khi bạn chạy chúng, bạn không có quyền kiểm soát trực tiếp cách chúng hoạt động. Hai loại chương trình cuối cùng này thì rất khác.
Line-by-line (Dòng Từng Dòng)
Hình thức tương tác đơn giản nhất là từng dòng một. Vào buổi bình minh của lịch sử Unix, những lệnh này khá phổ biến vì chúng chạy trên các máy teletype: những chiếc máy đánh chữ được “nâng cấp” hoạt động từng dòng một.
Ngày nay, những chương trình này thực sự có cảm giác như chúng “chỉ tương tác trên danh nghĩa”, nhưng vào những năm 1960, chúng khá mang tính cách mạng. Nếu bạn đủ dũng cảm, bạn có thể sống lại những ngày xưa cũ với trình soạn thảo văn bản gốc, ed
:
Ảnh minh họa trình soạn thảo văn bản ed trong terminal, hiển thị các lệnh để tạo và lưu tệp văn bản.
Đoạn hội thoại ed
này cho thấy các lệnh viết văn bản “hello world” vào một tệp có tên foo.txt
. Một số dòng đó được người dùng gõ: “a” là lệnh để thêm văn bản vào bộ đệm, “,p” in bộ đệm hiện tại, và “w” ghi bộ đệm vào một tệp. Sau khi ghi, ed
báo cáo số byte đã ghi, trong trường hợp này là 13.
Nếu bạn nhớ một điều về ed
, đó phải là lệnh “q” để thoát chương trình. Nó sẽ không lưu bất kỳ văn bản mới nào bạn đã nhập, nhưng nếu bạn vô tình chạy ed
, gõ “q” theo sau là Enter sẽ giúp bạn thoát khỏi nó nhanh nhất có thể!
Như bạn thấy, việc chỉnh sửa văn bản từng dòng là một quá trình gian nan và có thể dễ mắc lỗi. Chương trình ed
có thể hữu ích trong trường hợp khẩn cấp, nhưng các chương trình line-by-line nhìn chung đã lỗi thời.
TUI (Text-User Interface)
Một giải pháp thay thế tốt hơn nhiều cho các chương trình tương tác, đặc biệt là các trình soạn thảo văn bản, là kiểu TUI: giao diện người dùng văn bản. Tên gọi này phân biệt các chương trình này với các ứng dụng GUI (Graphical User Interface – giao diện đồ họa), vốn sử dụng đồ họa để đạt được cùng một loại kết quả: một chương trình thực sự tương tác.
Trình soạn thảo văn bản vim
vẫn dựa nhiều vào lệnh, nhưng bạn có thể sử dụng nó để di chuyển trong một tệp văn bản, tìm kiếm văn bản, xóa toàn bộ các khối, và xem mọi thứ xảy ra trên màn hình, trong thời gian thực. Các TUI hiện đại sử dụng rộng rãi màu sắc và các ký tự vẽ hộp để mô phỏng một giao diện đồ họa:
Hình ảnh minh họa giao diện người dùng văn bản (TUI) của ứng dụng Bagels, sử dụng các khung hiển thị nhiều tính năng đồng thời trên màn hình.
Mặc dù bạn sẽ không phải lúc nào cũng thấy các tài liệu tham khảo về các loại chương trình này, nhưng việc biết chúng tồn tại và hiểu chúng làm gì là rất hữu ích. Mỗi loại có những điểm mạnh riêng biệt và có thể được sử dụng trong các ngữ cảnh nhất định để hoàn thành nhiều tác vụ đa dạng.
Kết luận
Việc khám phá các loại chương trình đa dạng trong Linux, từ các tiến trình nền tự động đến các công cụ dòng lệnh mạnh mẽ và các ứng dụng tương tác tiên tiến, mang lại cái nhìn sâu sắc về kiến trúc và sự linh hoạt của hệ điều hành này. Hiểu rõ sự khác biệt giữa daemon, cantrip, filter, sink, source, compiler, cũng như các chương trình tương tác line-by-line và TUI, không chỉ nâng cao kỹ năng sử dụng Linux của bạn mà còn giúp bạn lựa chọn công cụ phù hợp nhất cho từng tác vụ cụ thể. Linux là một hệ sinh thái phong phú với vô số cách để thực hiện công việc, và việc nắm vững các khái niệm cơ bản này sẽ mở ra cánh cửa cho hiệu suất và khả năng tùy biến vượt trội.
Hãy chia sẻ kinh nghiệm của bạn về các loại chương trình Linux yêu thích hoặc những mẹo sử dụng chúng trong phần bình luận bên dưới!