Linux thừa hưởng triết lý thiết kế mạnh mẽ và có nguyên tắc của Unix: các chương trình giao tiếp thông qua văn bản, có thể kết hợp với nhau qua các đường ống (pipelines), và mỗi chương trình chỉ thực hiện tốt một việc. Tuy nhiên, ngoài những nguyên tắc cơ bản đó, các chương trình trên Linux 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 này sẽ giúp người dùng và quản trị viên hệ thống tối ưu hóa cách tương tác và khai thác sức mạnh của hệ điều hành Linux một cách hiệu quả nhất.
Tiến Trình Nền (Background Processes)
Một hệ điều hành đa nhiệm như Linux có khả năng 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 sự điều khiển trực tiếp của người dùng được gọi là các tiến trình nền. Trong thực tế, 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”.
1. Daemon
Thuật ngữ “daemon” nghe có vẻ lạ, nhưng nó chỉ đơn giản có nghĩa là “tiến trình nền”. Một daemon thường sử dụng các kỹ thuật đặc biệt để duy trì hoạt động, bất kể điều gì khác xảy ra trên hệ thống. Chẳng hạn, nó có thể tạo ra một bản sao của chính nó (fork) để chạy độc lập với shell. Các dịch vụ như inetd
hoặc launchd
có thể thực hiện việc này thay mặt cho 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 “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, chúng thường thực hiện điều đó bằng cách gửi một tín hiệu chỉ dẫn daemon khởi động lại hoặc tải lại cấu hình. 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, sau đó dừng lại khi chúng hoàn thành nhiệm vụ.
2. Cantrip
Loại chương trình đơn giản nhất — được gọi một cách không chính thức là “cantrip” — sẽ chỉ thực hiện hành động mà không cần đầu vào hay tạo ra đầu ra. Những chương trình này thường hoạt động trên các 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 tiếp theo:
Lệnh rm trong Linux xóa tệp và không hiển thị đầu ra trên terminal.
Lệnh rm
có một số tùy chọn để kiểm soát cách nó hoạt động, nhưng sự đơn giản của nó nằm ở việc thiếu đầu vào và đầu ra trực tiếp.
3. 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 theo một cách nào đó, và có rất nhiều chương trình như vậy: cut
, head
, sort
, uniq
, v.v.
Lệnh grep
minh họa ý nghĩa của một bộ lọc đặc biệt tốt: nó quét từng dòng đầu vào, tái tạo nó làm đầ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 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 chuỗi nhiều lệnh 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.
4. Sink (Bộ Thu)
Ngược lại với các 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 có đầu ra hiển thị trên màn hình terminal của bạn. Một ví dụ là lpr
, trình in dòng, dùng để in một tệp hoặc đầu vào 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.
5. Source (Nguồn)
Đối lập với một chương trình sink là một “source”, một chương trình tạo ra đầu ra mà không xử lý bất kỳ đầu vào nào. Các chương trình source lấy dữ liệu 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ê các tệp, nhưng nó không bao giờ xử lý đầu vào 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 một 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 ~/.*
6. Compiler (Trình Biên Dịch)
Một 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 giống 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 “c” cho “compiler”: cc
, javac
, hoặc rustc
. Một trình biên dịch hơi giống một 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 thành một loại khác.
Trình biên dịch C, cc
, minh họa 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 đối với hai tệp — file1.c
và file2.c
— tạo ra một tệp thứ ba có tên là program
. Ở đây, đối số “-o” là viết tắt của “output file” (tệp đầu ra).
Điều quan trọng cần lưu ý là một trình biên dịch có thể lấy thêm các tệp bổ sung làm nguồn, tùy thuộc vào nhiệm vụ của nó 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 ra chương trình cuối cùng, ngay cả khi nó không được đặt tên rõ ràng khi bạn chạy lệnh.
Đây là một phần làm cho các trình biên dịch trở nên phức tạp: chúng có thể thực hiện nhiều điều đằng sau hậu trường mà không cần được chỉ dẫn trực tiếp.
Chương Trình Tương Tác (Interactive Programs)
Các chương trình đã đề cập ở trên đều chạy 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 rất khác biệt.
7. Line-by-line (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 máy đánh chữ được cường điệu hóa chỉ 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 đủ can đảm, bạn có thể sống lại những ngày xưa với trình soạn thảo văn bản gốc, ed
:
Chương trình ed trong terminal Linux minh họa các lệnh tạo và lưu tệp văn bản.
Bản ghi 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
, đó là lệnh “q” để thoát khỏi 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 có thể thấy, chỉnh sửa văn bản từng dòng là một quá trình gian khổ và 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.
8. TUI (Text-User Interface – Giao Diện Người Dùng Văn Bản)
Một lựa chọn 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 này phân biệt những chương trình này với các ứng dụng GUI (giao diện đồ họa người dùng), 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:
Giao diện TUI Bagels sử dụng các khung để hiển thị nhiều tính năng đồng thời.
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ề những 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 ưu điểm riêng 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ụ khác nhau.
Kết Luận
Việc khám phá các loại chương trình Linux khác nhau – từ những daemon
chạy ẩn mình trong nền, các công cụ CLI
mạnh mẽ như filter
, sink
, source
, cantrip
, đến những compiler
phức tạp và các ứng dụng interactive
như TUI
– đã cho chúng ta cái nhìn sâu sắc về cách hệ điều hành này hoạt động. Mỗi loại chương trình đều có vai trò và cách tương tác riêng, phản ánh triết lý thiết kế linh hoạt và mạnh mẽ của Unix mà Linux kế thừa.
Hiểu rõ sự khác biệt giữa các kiểu chương trình này không chỉ giúp bạn sử dụng Linux hiệu quả hơn mà còn trang bị kiến thức nền tảng để giải quyết các vấn đề phức tạp, xây dựng các tập lệnh tự động hóa và khai thác tối đa tiềm năng của hệ thống. Hãy tiếp tục tìm hiểu và thực hành để nắm vững hơn các công cụ này, và đừng ngần ngại chia sẻ những phát hiện hoặc câu hỏi của bạn trong phần bình luận bên dưới!