Dễ dàng hình dung mọi thứ hơn nếu bạn nghĩ về những gì đang thực sự xảy ra với "chuyển hướng" và "đường ống". Chuyển hướng và đường ống trong bash làm một việc: sửa đổi nơi mô tả tệp quy trình 0, 1 và 2 điểm đến (xem / Proc / [pid] / fd / *).
Khi một đường ống hoặc "|" Toán tử có mặt trên dòng lệnh, điều đầu tiên xảy ra là bash tạo ra fifo và trỏ lệnh FD 1 của bên trái tới fifo này và trỏ FD 0 của lệnh bên phải vào cùng fifo.
Tiếp theo, các toán tử chuyển hướng cho mỗi bên được đánh giá từ trái sang phải và các cài đặt hiện tại được sử dụng mỗi khi xảy ra sự trùng lặp của bộ mô tả. Điều này rất quan trọng vì vì đường ống được thiết lập đầu tiên, FD1 (bên trái) và FD0 (bên phải) đã được thay đổi so với những gì chúng có thể thường có, và bất kỳ sự trùng lặp nào trong số này sẽ phản ánh thực tế đó.
Do đó, khi bạn gõ một cái gì đó như sau:
command 2>&1 >/dev/null | grep 'something'
Đây là những gì xảy ra, theo thứ tự:
- một đường ống (fifo) được tạo ra. "Lệnh FD1" được chỉ vào đường ống này. "grep FD0" cũng được chỉ vào đường ống này
- "Lệnh FD2" được trỏ đến nơi "lệnh FD1" hiện đang trỏ (đường ống)
- "lệnh FD1" được trỏ đến / dev / null
Vì vậy, tất cả đầu ra mà "lệnh" ghi vào FD 2 (stderr) của nó đi đến đường ống và được đọc bởi "grep" ở phía bên kia. Tất cả đầu ra mà "lệnh" ghi vào FD 1 (stdout) thực hiện theo cách của nó thành / dev / null.
Nếu thay vào đó, bạn chạy như sau:
command >/dev/null 2>&1 | grep 'something'
Đây là những gì xảy ra:
- một đường ống được tạo và "lệnh FD 1" và "grep FD 0" được chỉ vào nó
- "lệnh FD 1" được trỏ đến / dev / null
- "Lệnh FD 2" được chỉ đến nơi FD 1 hiện đang trỏ (/ dev / null)
Vì vậy, tất cả các thiết bị xuất chuẩn và thiết bị xuất chuẩn từ "lệnh" chuyển đến / dev / null. Không có gì đi vào đường ống, và do đó "grep" sẽ đóng mà không hiển thị bất cứ điều gì trên màn hình.
Cũng lưu ý rằng các chuyển hướng (mô tả tệp) có thể chỉ đọc (<), chỉ ghi (>) hoặc đọc-ghi (<>).
Một lưu ý cuối cùng. Cho dù một chương trình viết một cái gì đó cho FD1 hoặc FD2, hoàn toàn phụ thuộc vào lập trình viên. Thực hành lập trình tốt chỉ ra rằng các thông báo lỗi sẽ chuyển đến FD 2 và đầu ra bình thường sang FD 1, nhưng bạn sẽ thường thấy lập trình cẩu thả trộn lẫn hai hoặc bỏ qua quy ước.