Nếu đã từng sử dụng pipe và redirection trong Linux shell, đôi khi bạn cũng sẽ cần phải sử dụng tiện ích tee
.
Tee giữ nhiệm vụ gì?
Một lệnh như ls
sẽ hiển thị nội dung của thư mục hiện hành. Nói cách khác, nó hiển thị các nội dung này thành một stdout (standard output - đầu ra tiêu chuẩn), thường là màn hình của bạn, hoặc chính xác hơn là màn hình terminal ảo.
Một lệnh như ls > file123
sẽ không hiển thị gì trên màn hình. Đó là vì dấu >
chuyển hướng tất cả đầu ra thành một file thay vì hiển thị nó thành stdout. Bây giờ file123 sẽ được lấp đầy bằng các nội dung được hiển thị trước đó trên màn hình.
Để hiển thị nội dung của thư mục trên màn hình và ghi nó vào một file, bạn phải sử dụng hai lệnh. Nhưng với tee
, bạn có thể làm cả hai điều này cùng một lúc.
ls | tee file123
Tại sao nên sử dụng Tee khi bạn có thể chạy một lệnh tương tự hai lần?
Trong ví dụ trên, rõ ràng là bạn không cần tee
nếu bạn có thể thực thi ls
bình thường, sau đó thực hiện lại và chuyển hướng đầu ra thành một file. Tuy nhiên, bạn sẽ gặp các tình huống trong đó đầu ra là duy nhất. Hãy tưởng tượng tình huống bạn đang cố gắng chẩn đoán một vấn đề. Bạn chạy:
diagnose | tee error.log
Các lỗi bạn nhận được có thể là duy nhất. Bạn muốn chúng được hiển thị trên màn hình để bạn có thể thấy những gì đang diễn ra khi kiểm tra mọi thứ. Nhưng bạn cũng muốn những lỗi đó được lưu vào một file, để xem lại sau đó hoặc dán đầu ra vào một diễn đàn thảo luận và tham khảo ý kiến mọi người về nó.
Một tình huống khác thường gặp phải mà bạn có thể cần đến tee
, đó là khi bạn muốn đưa đầu ra của lệnh đến một vị trí mà chỉ người dùng root mới có thể đọc hoặc ghi. Lệnh sau không hoạt động:
/sbin/blkid > /root/somefile
Sau đó, bạn có thể nghĩ, chỉ cần sử dụng sudo
! Nhưng bạn sẽ ngạc nhiên khi lệnh này cũng không hoạt động:
sudo blkid > /root/somefile
Đó là vì sau khi sudo blkid
thực thi, bạn vẫn đăng nhập với tư cách không phải là người dùng root. Và shell (thường là bash) cố gắng ghi vào /root/somefile với thông tin người dùng thông thường của bạn. Để giải quyết điều này, bạn có thể sử dụng tee
:
/sbin/blkid | sudo tee /root/somefile
Nối văn bản và chuyển hướng lỗi
Tee
là một lệnh hữu ích nhưng đơn giản. Một lệnh command | tee somefile
cơ bản thường đủ dùng trong hầu hết mọi tình huống. Tuy nhiên, có 2 trường hợp mà bạn sẽ cần đến những lời khuyên này.
Điều đầu tiên cần biết là tee
, theo mặc định, luôn ghi đè lên một file. Nếu bạn chạy:
ls | tee somefile
Rồi sau đó chạy:
ls /tmp | tee somefile
Lệnh thứ hai sẽ ghi đè lên nội dung của somefile và bạn sẽ chỉ thấy nội dung của lệnh cuối cùng được thực thi. Để thay đổi hành vi này, bạn có thể tạo văn bản nối thêm tee
thay vì ghi đè. Để làm như vậy, chỉ cần sử dụng switch lệnh -a.
ls | tee -a somefile
Điều thứ hai cần biết là không phải tất cả đầu ra đều giống nhau. Các thông báo lỗi được xử lý khác nhau và mặc dù xuất hiện trên màn hình, nhưng chúng không được coi là stdout, mà được coi là stderr và không được tee
xử lý. Sau đây là một ví dụ về grep
.
grep -r L2TP /etc | tee somefile
Kết quả được hiển thị sẽ giống như hình ảnh sau đây:
Thông báo Permission denied được viết thành stderr. Điều duy nhất được viết thành stdout là phần văn bản được highlight. Đó là lý do tại sao bạn nhận thấy rằng nội dung của “somefile” là những gì được hiển thị trong hình ảnh dưới đây:
Trong trường hợp này, grep
được sử dụng để tìm kiếm văn bản và rất hữu ích khi các thông báo lỗi không được chuyển hướng đến file. Các thông báo lỗi chỉ lấp đầy file với những thông tin không cần thiết. Bạn chỉ muốn xem kết quả tìm được. Nhưng khi bạn cần thông báo lỗi, hãy sử dụng 2>&1
, để chuyển hướng stderr thành stdout.
grep -r L2TP /etc 2>&1 | tee somefile
Với lệnh này, bạn sẽ nhận thấy rằng somefile bây giờ cũng chứa các thông báo lỗi.
Hy vọng rằng, hướng dẫn này bao gồm mọi thứ bạn cần để tận dụng tối đa lệnh tee
. Nhưng nếu bạn gặp phải tình huống khó xử lý nào đó với tee
, hãy để lại ý kiến trong phần bình luận bên dưới để mọi người cùng chia sẻ.
Chúc bạn sử dụng lệnh tee
thành công!