Cách Pipe và Redirect như một chuyên gia trong dòng lệnh Linux

Tác giả Starlink, T.M.Một 29, 2024, 04:10:20 CHIỀU

« Chủ đề trước - Chủ đề tiếp »

0 Thành viên và 1 Khách đang xem chủ đề.

Nhiều người cùng làm thì công việc sẽ nhẹ nhàng hơn.

  • Các lệnh Linux có thể sử dụng các luồng chuẩn để nhập, xuất và gửi thông báo lỗi.
  • Chuyển hướng sẽ gửi luồng đầu ra đến một tệp thay vì cửa sổ thiết bị đầu cuối.
  • Đường ống cho phép bạn nối các lệnh lại với nhau, do đó đầu ra của lệnh này sẽ trở thành đầu vào của lệnh khác.

Trên Linux, các đường ống và chuyển hướng cho phép bạn sử dụng đầu ra từ các lệnh theo những cách mạnh mẽ. Ghi lại trong các tệp hoặc sử dụng làm đầu vào với các lệnh khác. Sau đây là những gì bạn cần biết.

1. Luồng là gì?

Linux, giống như các hệ điều hành giống Unix khác, có khái niệm về luồng. Mỗi tiến trình có một luồng đầu vào gọi là stdin, một luồng đầu ra gọi là stdout và một luồng lỗi gọi là stderr. Luồng Linux, giống như luồng trong thế giới thực, có hai điểm cuối. Chúng có một nguồn hoặc đầu vào và một đích hoặc đầu ra.


Luồng đầu vào có thể đến từ bàn phím đến lệnh, cho phép bạn gửi văn bản như thông tin hoặc lệnh đến quy trình. Luồng đầu ra đến từ lệnh, thường là đến cửa sổ terminal. Luồng stderr cũng ghi vào cửa sổ terminal.

Bạn có thể chuyển hướng luồng và bạn có thể dẫn chúng. Chuyển hướng có nghĩa là gửi đầu ra đến một nơi nào đó khác ngoài cửa sổ terminal. Dẫn có nghĩa là lấy đầu ra của một lệnh và sử dụng nó làm đầu vào cho một lệnh khác.

Tính năng này cho phép bạn kết nối các lệnh lại với nhau để tạo ra các giải pháp phức tạp từ một loạt các lệnh đơn giản khi làm việc cùng nhau.

2. Chuyển hướng luồng

Dạng chuyển hướng đơn giản nhất lấy đầu ra từ lệnh và gửi đến tệp. Ngay cả trường hợp tầm thường này cũng có thể hữu ích. Có lẽ bạn cần bản ghi đầu ra của lệnh hoặc có quá nhiều đầu ra cuộn qua khiến bạn không thể đọc được.

Trên PC thử nghiệm này, lệnh du xuất ra 1380 dòng văn bản. Chúng tôi sẽ gửi nó vào một tệp.

Mã nguồn [Chọn]
du > disk-usage.txt
Dấu ngoặc vuông góc phải yêu cầu shell chuyển hướng đầu ra stdout từ lệnh du vào tệp có tên disk-usage.txt. Không có đầu ra nào được gửi đến cửa sổ terminal.

Chúng ta có thể sử dụng ls để xác minh tệp đã được tạo và wc để đếm số dòng, từ và chữ cái trong tệp. Như mong đợi, wc báo cáo rằng tệp có 1380 dòng.

Mã nguồn [Chọn]
ls
wc disk-usage.txt

Kiểu chuyển hướng này tạo hoặc ghi đè lên tệp mỗi lần bạn sử dụng. Nếu bạn muốn thêm văn bản được chuyển hướng vào cuối tệp hiện có, hãy sử dụng dấu ngoặc vuông góc phải kép ">>", như thế này.

Mã nguồn [Chọn]
ls /home/dave-mckay/ -R >> disk-usage.txt
wc disk-usage.txt

Sử dụng tùy chọn -N (số dòng) với less, chúng ta có thể xác minh rằng thông tin mới đã được thêm vào sau dòng 1380.


Nếu chúng ta viết lệnh tạo ra lỗi, chúng ta sẽ thấy rằng, vì chúng ta chỉ chuyển hướng stdout nên mọi thông báo lỗi stderr vẫn được gửi đến cửa sổ thiết bị đầu cuối.

Mã nguồn [Chọn]
wc disk-usage.txt missing-file.txt > results.txt
wc: missing-file.txt: No such file or directory
cat results.txt

Kết quả cho disk-usage.txt được gửi đến tệp results.txt, nhưng thông báo lỗi cho tệp missing-file.txt không tồn tại được gửi đến cửa sổ thiết bị đầu cuối.

Chúng ta có thể thêm các chỉ số số vào dấu ngoặc vuông góc phải để làm rõ luồng nào chúng ta đang chuyển hướng. Luồng 1 là stdout và luồng 2 là stderr. Chúng ta có thể chuyển hướng stdout sang một tệp và stderr sang tệp khác khá dễ dàng.

Mã nguồn [Chọn]
wc disk-usage.txt missing-file.txt 1> results.txt 2> error.txt
cat results.txt
cat error.txt

Nếu bạn muốn cả hai luồng được chuyển hướng đến một tệp duy nhất, chúng ta sẽ chuyển hướng stdout đến một tệp và yêu cầu shell chuyển hướng stderr đến cùng đích mà stdout sẽ hướng đến.

Mã nguồn [Chọn]
wc disk-usage.txt missing-file.txt 1> results.txt 2>&1
cat results.txt

Bất kỳ thông báo lỗi nào cũng sẽ được ghi lại và gửi đến cùng một tệp với stdout.

Bạn có thể không muốn lưu trữ bất kỳ đầu ra nào cả, bạn chỉ không muốn bất cứ thứ gì được ghi vào cửa sổ terminal. Tệp thiết bị null, âm thầm tiêu thụ mọi thứ được gửi đến nó, là một đích đến tiện dụng để gửi đầu ra màn hình không mong muốn.

Mã nguồn [Chọn]
rm disk-usage.txt missing-file.txt 1> /dev/null 2>&1
Cả thông báo stdout và stderr đều không được ghi vào cửa sổ terminal, ngay cả khi một trong các tệp chúng ta đang xóa không tồn tại.

Một mẹo cuối cùng bạn có thể thực hiện với lệnh chuyển hướng là đọc tệp vào luồng stdin của lệnh.

Mã nguồn [Chọn]
wc < /etc/passwd
Bạn có thể kết hợp điều này với việc chuyển hướng đầu ra.

Mã nguồn [Chọn]
wc < /etc/passwd > results.txt
cat results.txt

Sử dụng chuyển hướng để đọc một tệp vào luồng stdin của lệnh và gửi đầu ra đến một tệp khác.

3. Đưa dòng chảy qua đường ống

Pipe chuyển hướng stdout của một lệnh một cách hiệu quả và gửi nó đến stdin của lệnh khác. Piping là một trong những khía cạnh mạnh mẽ nhất của dòng lệnh và có thể chuyển đổi cách bạn sử dụng các lệnh và tiện ích cốt lõi của Linux.

Để chuyển đầu ra của một lệnh sang lệnh khác, chúng ta sử dụng ký hiệu ống "|". Ví dụ, nếu chúng ta muốn liệt kê đệ quy tất cả các tệp và thư mục con trong thư mục gốc của bạn, bạn sẽ thấy một vệt mờ nhanh khi đầu ra từ lệnh ls chạy qua trong cửa sổ terminal.

Bằng cách đưa lệnh ls vào less, chúng ta sẽ có được kết quả hiển thị trong trình xem tệp thuận tiện.

Mã nguồn [Chọn]
ls -R ~ | less

Cách này hiệu quả hơn so với quy trình thủ công gồm hai bước là gửi đầu ra đến một tệp và mở tệp đó nhanh hơn.

4. Dẫn đầu ra qua lệnh khác

Đường ống thực sự phát huy tác dụng khi lệnh thứ hai tiếp tục xử lý đầu ra của lệnh thứ nhất.

Hãy đếm số lượng tài khoản người dùng và tài khoản giả người dùng trên máy tính của bạn. Chúng ta sẽ sử dụng cat để dump nội dung của tệp /etc/passwd và chuyển nó đến wc. Tùy chọn -l (dòng) sẽ đếm số lượng dòng trong tệp đó. Vì mỗi tài khoản chỉ có một dòng nên nó sẽ đếm các tài khoản cho chúng ta.

Mã nguồn [Chọn]
cat /etc/passwd | wc -l
Nghe có vẻ nhiều đấy. Chúng ta hãy xem tên của các tài khoản đó. Lần này chúng ta sẽ chuyển hướng cat vào awk. Lệnh awk được yêu cầu sử dụng dấu hai chấm ":" làm dấu phân cách trường và in trường đầu tiên.

Mã nguồn [Chọn]
cat /etc/passwd | awk -F: '{print $1}'

Chúng ta có thể tiếp tục thêm lệnh. Để sắp xếp danh sách, hãy thêm lệnh sort để đầu ra từ awk đi đến lệnh sort.

Mã nguồn [Chọn]
cat /etc/passwd | awk -F: '{print $1}' | sort

5. Đầu ra đường ống thông qua một chuỗi lệnh

Đây là một tập hợp bốn lệnh được nối với ba đường ống. Lệnh ps liệt kê các tiến trình đang chạy. Tùy chọn -e (mọi thứ) liệt kê tất cả các tiến trình và tùy chọn -o (đầu ra) chỉ định thông tin nào cần báo cáo. Mã thông báo comm có nghĩa là chúng ta chỉ muốn xem tên tiến trình.

Danh sách tên tiến trình sau đó được chuyển vào grep, lọc ra các tiến trình có tên là chrome. Danh sách đã lọc đó được đưa vào sort để sắp xếp danh sách. Danh sách đã sắp xếp sau đó được chuyển vào uniq. Tùy chọn -c (count) đếm các tên tiến trình duy nhất. Sau đó, chỉ để vui, chúng ta làm điều tương tự cho firefox.

Mã nguồn [Chọn]
ps -e -o comm | grep chrome | sort | uniq -c
ps -e -o comm | grep firefox | sort | uniq -c

6. Sự kết hợp vô tận

Không có giới hạn về số lượng lệnh bạn có thể kết hợp với nhau, chỉ cần lưu ý rằng mỗi lệnh được mở trong một subshell mới của riêng nó. Điều đó không phải là vấn đề ngay cả trên máy tính hiện đại có thông số kỹ thuật khiêm tốn nhất, nhưng nếu bạn thấy chậm lại, hãy cân nhắc đơn giản hóa các lệnh của bạn. Hoặc hãy kiên nhẫn.