Nếu bạn đã từng đọc qua một vài shellscript thì nhất định bạn đã từng gặp một đoạn mã kỳ quặc như dưới đây:
echo hello >/dev/null 2>&1
Cả hai cú pháp “>/dev/null 2>&1” và “2>&1 >/dev/null” đều được sử dụng để chuyển hết output sang null
, tức là không xuất hiện gì trên màn hình console. Tuy nhiên, chúng có sự khác biệt về thứ tự định tuyến.
Trong “>/dev/null 2>&1”, thứ tự định tuyến là đầu tiên chuyển output của lệnh sang null (>/dev/null
) và sau đó chuyển stderr sang stdout (2>&1
). Kết quả là stdout và stderr đều bị chuyển sang null.
Trong “2>&1 >/dev/null”, thứ tự định tuyến là đầu tiên chuyển stderr sang stdout (2>&1
) và sau đó chuyển stdout sang null (>/dev/null
). Kết quả là chỉ stderr bị chuyển sang null, còn stdout vẫn xuất hiện trên màn hình console.
Ví dụ:
- Lệnh
ls /root > /dev/null 2>&1
sẽ gửi output (nếu có) sang /dev/null và gửi error (nếu có) sang stdout (cùng với output) để chúng có thể được gửi đến thiết bị đầu cuối hoặc file. - Lệnh
echo "Hello world" 2>&1 > /dev/null
sẽ gửi error sang stdout (cùng với output) và gửi output sang /dev/null. - Lệnh
find / -name "test" 2>&1 >/dev/null
sẽ gửi error sang stdout (cùng với output) và gửi output sang /dev/null. - Lệnh
ssh user@host "ls /var/log/*log 2>&1 >/dev/null | grep error"
sẽ ssh vào host, chạy lệnhls /var/log/*log
, gửi error sang stdout (cùng với output) và gửi output sang /dev/null, và sau đó grep “error” từ output và hiển thị kết quả.