Về mặt kỹ thuật, “/dev/null” là một file thiết bị ảo. Đối với các chương trình có liên quan, chúng được coi như những file thực sự. Các tiện ích có thể yêu cầu dữ liệu từ loại nguồn này và hệ điều hành sẽ cung cấp dữ liệu cho chúng. Nhưng, thay vì đọc từ ổ đĩa, hệ điều hành sẽ tạo ra dữ liệu này một cách linh hoạt. Ví dụ về một file như vậy chính là “/dev/zero”.
Tuy nhiên, trong trường hợp này, bạn sẽ ghi vào một file thiết bị. Bất cứ điều gì bạn ghi vào “/dev/null”, đều bị loại bỏ và lãng quên. Để hiểu lý do tại sao điều này hữu ích, trước tiên bạn phải có hiểu cơ bản về đầu ra tiêu chuẩn (standard output) và lỗi tiêu chuẩn (standard error) trong các hệ điều hành kiểu Linux hoặc * nix.
Tìm hiểu về /dev/null trong Linux
stdout và stderr
Một tiện ích dòng lệnh có thể tạo ra hai loại đầu ra. Đầu ra tiêu chuẩn được gửi đến stdout. Lỗi được gửi đến stderr.
Theo mặc định, stdout và stderr được liên kết với cửa sổ terminal (hoặc console). Điều này có nghĩa là mọi thứ được gửi tới stdout và stderr thường được hiển thị trên màn hình. Nhưng thông qua chuyển hướng shell, bạn có thể thay đổi hành vi này. Ví dụ, bạn có thể chuyển hướng stdout vào một file. Bằng cách này, thay vì hiển thị đầu ra trên màn hình, dữ liệu sẽ được lưu vào một file để bạn đọc sau - hoặc bạn có thể chuyển hướng stdout sang thiết bị vật lý, ví dụ, màn hình LED hoặc LCD kỹ thuật số.
Quantrimang.com có một bài viết đầy đủ về Pipe trong Unix/Linux, nếu bạn muốn tìm hiểu thêm.
- Với 2> bạn chuyển hướng thông báo lỗi tiêu chuẩn. Ví dụ:
2>/dev/null
hoặc2>/home/user/error.log
. - Với 1> bạn chuyển hướng đầu ra tiêu chuẩn.
- Với &> bạn chuyển hướng cả lỗi tiêu chuẩn và đầu ra tiêu chuẩn.
Sử dụng /dev/null để thoát khỏi kết quả đầu ra bạn không cần
Như đã nói ở trên, có hai loại đầu ra: Đầu ra tiêu chuẩn và lỗi tiêu chuẩn. Trường hợp sử dụng đầu tiên là lọc ra đầu ra hoặc lỗi tiêu chuẩn. Sẽ dễ hiểu hơn khi xem xét thông qua một ví dụ thực tế. Ví dụ, bạn đang tìm kiếm một chuỗi trong “/sys” để tìm những file liên quan đến cài đặt nguồn.
grep -r power /sys/
Sẽ có rất nhiều file mà người dùng không phải root không thể đọc được. Điều này dẫn đến nhiều lỗi “Permission denied”.
Những thứ này làm lộn xộn đầu ra và làm bạn khó phát hiện ra kết quả mình đang tìm kiếm. Vì các lỗi “Permission denied” là một phần của stderr, nên bạn có thể chuyển hướng chúng sang “/dev/null”.
grep -r power /sys/ 2>/dev/null
Như bạn có thể thấy, kết quả của lệnh này dễ đọc hơn nhiều.
Trong những trường hợp khác, việc thực hiện điều ngược lại (lọc ra đầu ra tiêu chuẩn để bạn chỉ có thể thấy lỗi) có thể hữu ích.
ping google.com 1>/dev/null
Ảnh chụp màn hình ở trên cho thấy, không cần chuyển hướng, ping sẽ hiển thị đầu ra bình thường của nó khi có thể đến máy đích. Trong lệnh thứ hai, không có gì được hiển thị trong khi mạng đang trực tuyến, nhưng ngay khi nó bị ngắt kết nối, chỉ có thông báo lỗi được hiển thị.
Bạn có thể chuyển hướng cả stdout và stderr đến hai địa điểm khác nhau.
ping google.com 1>/dev/null 2>error.log
Trong trường hợp này, các thông báo stdout sẽ không được hiển thị hoàn toàn và thông báo lỗi sẽ được lưu vào file error.log.
Chuyển hướng tất cả đầu ra sang /dev/null
Đôi khi, việc loại bỏ tất cả đầu ra có thể sẽ rất hữu ích. Có hai cách để làm điều này.
grep -r power /sys/ >/dev/null 2>&1
Chuỗi >/dev/null có nghĩa là gửi stdout đến /dev/null, và phần thứ hai, 2>&1, có nghĩa là gửi stderr đến stdout. Trong trường hợp này, bạn phải coi stdout là &1, thay vì chỉ đơn giản là 1. Việc ghi 2>1 sẽ chỉ chuyển hướng stdout sang một file có tên là 1.
Điều quan trọng cần lưu ý ở đây là thứ tự rất quan trọng. Nếu bạn đảo ngược các tham số chuyển hướng như thế này:
grep -r power /sys/ 2>&1 >/dev/null
Lệnh sẽ không hoạt động như dự định. Lý do là vì ngay sau khi 2>&1 được diễn giải, stderr được gửi đến stdout và hiển thị trên màn hình. Tiếp theo, stdout bị loại bỏ khi gửi tới “/dev/null”. Kết quả cuối cùng là bạn sẽ thấy các lỗi trên màn hình thay vì triệt tiêu tất cả đầu ra. Nếu bạn không thể ghi nhớ đúng thứ tự, thì có một cách chuyển hướng đơn giản, dễ nhập hơn nhiều:
grep -r power /sys/ &>/dev/null
Trong trường hợp này, &>/dev/null tương đương với việc yêu cầu "chuyển hướng cả stdout và stderr đến vị trí này".
Các ví dụ khác có thể hữu ích khi chuyển hướng đến /dev/null
Giả sử bạn muốn xem ổ đĩa của mình có thể đọc dữ liệu tuần tự nhanh như thế nào. Bài kiểm tra không cực kỳ chính xác, nhưng kết quả cũng đủ tin cậy. Bạn có thể sử dụng dd cho việc này, nhưng dd có thể xuất ra stdout hoặc được hướng dẫn để ghi vào file. Với of=/dev/null, bạn có thể yêu cầu dd ghi vào file ảo này. Thậm chí, bạn không cần phải sử dụng chuyển hướng shell ở đây. if= chỉ định vị trí của file đầu vào sẽ được đọc; of= chỉ định tên của file đầu ra, nơi ghi dữ liệu.
dd if=debian-disk.qcow2 of=/dev/null status=progress bs=1M iflag=direct
Trong một số trường hợp, bạn có thể muốn xem xét việc có thể tải xuống nhanh như thế nào từ máy chủ. Nhưng bạn sẽ không muốn ghi vào ổ đĩa nếu không cần thiết. Nói một cách đơn giản, đừng ghi vào một file thông thường, hãy viết vào “/dev/null”.
wget -O /dev/null http://ftp.halifax.rwth-aachen.de/ubuntu-releases/18.04/ubuntu-18.04.2-desktop-amd64.iso
Hy vọng rằng, các ví dụ trong bài viết này có thể truyền cảm hứng cho bạn trong việc tìm ra những cách sáng tạo của riêng mình để sử dụng “/dev/null”.
Nếu bạn biết một trường hợp sử dụng thú vị cho file thiết bị đặc biệt này, hãy để lại ý kiến trong phần bình luận dưới đây nhé!
Chúc bạn thực hiện thành công!