Piping và chuyển hướng câu lệnh trong Linux

Mở đầu

Trong Linux, các thao tác chủ yếu và thường xuyên của người sử dụng là việc gõ các dòng lệnh trên một cửa sổ Terminal. Mỗi câu lệnh của Linux thường sẽ bao gồm đầu vào (Input) và đầu ra (Output), ngoài ra phần lớn câu lệnh cũng có kèm theo các thông báo lỗi (Error Message). Nguyên lý thiết kế của các chương trình trong Linux là chỉ làm một nhiệm vụ và làm nhiệm vụ đó tốt nhất có thể. Tuy nhiên các công việc của người sử dụng lại không chỉ đơn giản là sử dụng một câu lệnh duy nhất, mà cần nhiều chương trình phối hợp để cùng thực hiện. Điều này thể hiện ở việc đầu ra của chương trình này lại là đầu vào của chương trình khác. Và như vậy theo cách thông thường ta sẽ cần chạy từng câu lệnh riêng biệt, và lấy đầu ra của câu lệnh này làm đầu vào của câu lệnh kia, việc này sẽ làm mất rất nhiều công sức do đầu ra của các chương trình thường sẽ dài và phức tạp. Trong Linux, có một tính năng giúp người sử dụng có thể giảm tải lượng công việc mất quá nhiều công sức này, đó là Piping - tính năng giúp chuyển hướng dòng thực thi của câu lệnh.

Cơ bản về Piping

Về cơ bản piping là một dạng chuyển hướng được sử dụng trong các dòng hệ điều hành Linux dùng để chuyển đầu ra của chương trình này cho chương trình khác dùng làm đầu vào để xử lý tiếp. Theo ý nghĩa, piping là một đường ống, tức là nó sẽ làm cho các câu lệnh trở thành một dòng xử lý nối tiếp nhau và liên tục, kết nối trực tiếp và tạm thời hai hoặc nhiều chương trình đơn giản thành một nhóm các chương trình phức tạp. Chính nhờ vậy mà một số nhiệm vụ có thể hoàn thành với hiệu suất cao mà không một chương trình riêng rẽ nào có thể thực hiện một mình được. Việc kết nối chương trình thông qua piping giúp cho các chương trình có thể hoạt động liên tục chứ không cần phải chờ dữ liệu từ các nơi lưu trữ tạm thời như tệp tin hoặc màn hình hiển thị, cũng không phải chờ cho chương trình trước đó hoàn thành mà có thể hoạt động ngay khi chương trình trước nó bắt đầu tạo dữ liệu đầu ra.

Luồng dữ liệu

Các chương trình trong Linux sẽ tự động được kết nối với 3 luồng dữ liệu khi chúng được thực thi:

  • stdin (standard input): đây là luồng sẽ đưa dữ liệu vào chương trình để xử lý.
  • stdout (standard output): luồng này dùng để xuất dữ liệu ra màn hình hiển thị sau khi quá trình thực thi hoàn tất mà không gặp lỗi.
  • stderr (standard error): luồng này có chức năng tương tự stdout, tuy nhiên nó chỉ dùng để in các thông báo lỗi và đồng thời khi đó tín hiệu lỗi cũng được gửi tới hệ điều hành.

Ngoài ra, tùy theo chương trình mà luồng stdout sẽ được thay thế bằng tệp tin hoặc máy in .... Việc liên kết các chương trình sẽ là việc đưa dữ liệu đầu ra của chương trình trước đến thẳng đầu vào của chương trình sau mà không để dữ liệu được in ra màn hình hiển thị hoặc file.

Các dạng chuyển hướng

Chuyển hướng tới file

  • Là một trong 2 cách chuyển hướng đơn giản nhất, với cách này, dữ liệu đầu ra sẽ được lưu vào file thay vì in ra màn hình hiển thị.
  • Để chuyển hướng 1 câu lệnh tới file, Linux cung cấp cho người sử dụng 2 cú pháp: < (ghi nội dung ra file từ điểm bắt đầu, nếu file đã có nội dung thì ghi đè) và << (tương tự < nhưng thay vì ghi đè lên nội dung cũ thì sẽ ghi từ điểm kết thúc của nội dung cũ)
  • Một vài VD:

Ghi nội dung ra file, nếu file không tồn tại thì một file mới sẽ được tạo

Ghi đè nội dung file cũ

Thêm nội dung cho file cũ

Chuyển hướng từ file

  • Là cách chuyển hướng đơn giản còn lại, đi cùng với Chuyển hướng tới file, cách này giống với việc đọc dữ liệu từ file và sử dụng dữ liệu đó làm đầu vào cho chương trình.
  • Chỉ có một ký hiệu duy nhất cho cách này là <
  • VD:

Trong VD này, nội dung của file được dùng làm đầu vào của câu lệnh wc, có thể thấy rõ được sự khác biệt của 2 lần thực thi là lần 1 thì đầu vào là 1 file, lần 2 thì đầu vào chỉ là nội dung của file (output của wc không còn tên file nữa)

Chuyển hướng tới stderr

  • Thông thường, khi một câu lệnh gặp lỗi, thông tin lỗi sẽ hiển thị luôn lên màn hình cùng với các dữ liệu đầu ra
  • Linux cung cấp ký hiệu 2> để đưa nội dung thông báo lỗi ra file thay vì màn hình hiển thị.
  • VD:

Cũng tương tự như chuyển hướng tới file, nhưng ở đây chỉ có thông báo lỗi được đưa vào file

Chuyển hướng tới câu lệnh khác

  • Sự chuyển hướng đặc biệt nhất, đưa đầu ra của một câu lệnh tới câu lệnh khác như đầu vào
  • Sử dụng ký hiệu | để chuyển hướng
  • Một vài VD:

Lời kết

  • Linux thật là tuyệt vời, các công việc cần xử lý bằng các dòng lệnh vốn đã nhanh, với sự trợ giúp của tính năng piping còn giúp công việc được nhanh chóng hơn.
  • Tính năng này cũng giúp cho việc gõ đi gõ lại các câu lệnh bớt đi sự nhàm chán, và đồng thời cũng làm tăng hiệu suất công việc.
  • Chỉ với các ký hiệu đơn giản (>, >>, <, 2>|) nhưng lại có thể giảm công sức đi rất nhiều.

Cảm ơn mọi người đã đọc bài viết (bow) (thankyou)

Tài liệu tham khảo