Tiêu chuẩn C cho biết rằng tệp luồng stdin, stdout và stderr phải được kết nối ở đâu đó, nhưng chúng không chỉ định vị trí, tất nhiên. Hoàn toàn khả thi để chạy một chương trình với họ được chuyển hướng:
some_program_of_yours >/dev/null 2>&1 </dev/null
Bài viết của bạn sẽ thành công - nhưng thông tin sẽ không đi đâu cả. Một cách tàn bạo hơn để chạy chương trình của bạn là:
some_program_of_yours >&- 2>&- </dev/null
Lần này, nó đã chạy mà không có luồng tệp mở cho tiêu chuẩn và tiêu chuẩn - không đúng tiêu chuẩn. Nó vẫn đọc từ/dev/null trong ví dụ, có nghĩa là nó không nhận được bất kỳ dữ liệu đầu vào hữu ích nào từ stdin.
Nhiều chương trình không bận tâm kiểm tra xem các kênh I/O chuẩn có đang mở hay không. Nhiều chương trình không bận tâm kiểm tra xem thông báo lỗi đã được viết thành công chưa. Tạo ra một dự phòng phù hợp như phác thảo bởi Tim Post và whitey04 không phải lúc nào cũng đáng nỗ lực. Nếu bạn chạy lệnh ls
với kết quả đầu ra của nó bị ức chế, nó sẽ chỉ đơn giản là làm những gì nó có thể và thoát với một tình trạng khác không:
$ ls; echo $?
gls
0
$ ls >&- 2>&-; echo $?
2
$
(Tested RHEL Linux.) Có thực sự không phải là một nhu cầu cho nó làm nhiều hơn. Mặt khác, nếu chương trình của bạn được yêu cầu chạy trong nền và ghi vào tệp nhật ký, nó có thể sẽ không viết nhiều cho stderr, trừ khi nó không mở được tệp nhật ký (hoặc phát hiện lỗi trên tệp nhật ký) .
Lưu ý rằng nếu bạn rơi trở lại trên syslog(3)
(hoặc POSIX), bạn không có cách nào biết liệu cuộc gọi của bạn có 'thành công' hay không; chức năng nhật ký hệ thống tất cả trở về không có thông tin trạng thái. Bạn chỉ cần giả định rằng họ đã thành công. Đó là khu nghỉ mát cuối cùng của bạn, do đó.
Nguồn
2011-01-31 01:03:42
Tôi tự hỏi tại sao điều này không nhận được nhiều phiếu bầu hơn là câu trả lời của tôi. +1. –
@Tim: cảm ơn, nhưng câu trả lời của bạn cũng cung cấp thông tin tốt - và bạn đã đến đó trước. Và điểm mấu chốt của bạn - sử dụng một chức năng thực hiện báo cáo lỗi, không phải một đoạn mã mỗi lần bạn cần báo cáo lỗi - là rất quan trọng. –