Liên quan đến bash shell, tôi thấy cách tốt nhất để nhớ là bằng cách hiểu những gì đang xảy ra.
Nếu tất cả những gì bạn muốn làm là nhớ cách lấy lệnh chính xác, bạn có thể thử
program > /results 2> /results
Đó là những gì tốt đẹp và rõ ràng đang diễn ra và dễ nhớ. I E
1
STDOUT sẽ /results
2
STDERR cũng sẽ trực tiếp đến/results
vấn đề là điều này không hoạt động như bạn mong đợi. xem xét những điều sau đây
tập tin: /tmp/poem.txt
the quick brown fox jumped over the lazy dog
và lệnh chạy
grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results
sau đó
$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
lazy dog
chuyện gì đã xảy ra ở đây
Sự hiểu biết của tôi là bash thiết lập chuyển hướng trỏ STDERR trực tiếp vào tệp /tmp/results
và vì bản chất của >
nó làm 2 việc
- thường tạo một tệp mới - trong trường hợp này cơ hội đã qua vì bash đã vượt qua thói quen này tại thời điểm đầu ra được tạo.
- chèn thẳng vào phần đầu của tập tin và không nối như
>>
không.
Vì vậy, trong trường hợp này STDERR, chèn trực tiếp vào phần đầu ghi /tmp/results
đè đầu ra của STDOUT.
Lưu ý: nếu bạn đã sử dụng >>
để nối thêm, bạn có thể thoát khỏi cú pháp này.
Tuy nhiên, để khắc phục sự cố bạn cần - không phải chuyển hướng STDERR - trực tiếp đến tệp, mà là để hợp nhất đầu ra của STDERR vào luồng STDOUT, do đó bạn không bị xung đột.
Sử dụng toán 2>&1
tử toán tử đạt được điều này
grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1
Các &
phép bash để phân biệt từ một file có tên 1
và 1
mô tả tập tin.
Đối với tôi, bản 2>&1
thân câu lệnh giải thích chính xác những gì đang xảy ra - STDERR đang được chuyển hướng tại chính STDOUT - và chỉ kết thúc ở đó /tmp/results
vì đó là điểm mà STDOUT được chỉ ra (gần như là một tác dụng phụ).
Trái ngược với những gì rất nhiều hướng dẫn yêu cầu, đó là 2>&1
gửi STDERR đến nơi mà STDOUT được chỉ. Nếu đó là sự thật - bạn vẫn sẽ gặp vấn đề về ghi đè.
Để biết thêm thông tin, hãy xem - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection
program 1> /dev/null 2>/dev/null
. Đôi khi, mặc dù bạn cần phải trộn lẫnstdout
vàstderr
cùng nhau để xem điều gì đang thực sự xảy ra - như đầu ra từ một quá trình biên dịch phức tạp đang được chuyển hướng đến một tệp. Trong trường hợp đó, tôi kết thúc việc này