it-mot-dan-vi.com

Sự khác biệt giữa 2> & 1> output.log và 2> & 1 | đầu ra tee.log

Tôi muốn biết sự khác biệt giữa hai lệnh sau

2>&1 > output.log 

2>&1 | tee output.log

Tôi thấy một trong những đồng nghiệp của tôi sử dụng tùy chọn thứ hai để chuyển hướng. Tôi biết 2> & 1 làm gì, câu hỏi duy nhất của tôi là mục đích của việc sử dụng tee nơi toán tử chuyển hướng đơn giản ">" có thể được sử dụng là gì?

36
Chander Shivdasani

Nhìn vào hai lệnh riêng biệt:

utility 2>&1 >output.log 

Ở đây, do các chuyển hướng được xử lý theo cách từ trái sang phải, luồng lỗi tiêu chuẩn trước tiên sẽ được chuyển hướng đến bất cứ nơi nào luồng đầu ra tiêu chuẩn đi (có thể đến bàn điều khiển), và sau đó luồng đầu ra tiêu chuẩn sẽ được chuyển hướng đến một tệp. Luồng lỗi tiêu chuẩn sẽ không được chuyển hướng đến tệp đó.

Hiệu quả có thể nhìn thấy của điều này sẽ là bạn có được những gì được tạo ra do lỗi tiêu chuẩn trên màn hình và những gì được tạo ra trên đầu ra tiêu chuẩn trong tệp.

utility 2>&1 | tee output.log

Tại đây, bạn chuyển hướng lỗi tiêu chuẩn đến cùng một nơi với luồng đầu ra tiêu chuẩn. Điều này có nghĩa là cả hai luồng sẽ được chuyển đến tiện ích tee dưới dạng luồng đầu ra xen kẽ duy nhất và dữ liệu đầu ra tiêu chuẩn này sẽ được lưu vào tệp đã cho bởi tee. Ngoài ra, dữ liệu sẽ được sao chép bởi tee trong bảng điều khiển (đây là những gì tee làm, nó sao chép luồng dữ liệu).

Cái nào được sử dụng tùy thuộc vào những gì bạn muốn đạt được.

Lưu ý rằng bạn sẽ không thể tái tạo hiệu ứng của đường ống thứ hai chỉ bằng > (như trong utility >output.log 2>&1, sẽ lưu cả đầu ra tiêu chuẩn và lỗi trong tệp bằng cách chuyển hướng đầu ra tiêu chuẩn đầu tiên sang output.log tập tin và sau đó chuyển hướng lỗi tiêu chuẩn đến nơi đầu ra tiêu chuẩn hiện đang diễn ra). Bạn sẽ cần sử dụng tee để lấy dữ liệu trong bảng điều khiển cũng như trong tệp đầu ra.


Ghi chú bổ sung:

Hiệu ứng hiển thị của lệnh đầu tiên,

utility 2>&1 >output.log 

sẽ giống như

utility >output.log

Tức là, đầu ra tiêu chuẩn đi đến tập tin và lỗi tiêu chuẩn đi đến bàn điều khiển.

Nếu một bước xử lý tiếp theo được thêm vào cuối mỗi lệnh trên, thì sẽ có một sự khác biệt lớn:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

Trong đường ống đầu tiên, more_stuff sẽ lấy luồng lỗi ban đầu từ utility làm dữ liệu đầu vào tiêu chuẩn của nó, trong khi ở đường ống thứ hai, vì đó chỉ là luồng đầu ra tiêu chuẩn được gửi qua một đường ống, more_stuff một phần của đường ống sẽ không có gì để đọc trên đầu vào tiêu chuẩn của nó.

15
Kusalananda

Biên tập

Vui lòng đảm bảo đọc các nhận xét về câu trả lời này - derobert .


Câu trả lời gốc

2>&1 >output.log có nghĩa là trước tiên bắt đầu gửi tất cả xử lý tệp 2 thứ (lỗi tiêu chuẩn) đến xử lý tệp 1 (đầu ra tiêu chuẩn) sau đó gửi tệp đó đến tệp output.log. Nói cách khác, gửi lỗi tiêu chuẩn và đầu ra tiêu chuẩn đến tệp nhật ký.

2>&1 | tee output.log giống với 2>&1 bit, nó kết hợp đầu ra tiêu chuẩn và lỗi tiêu chuẩn trên luồng đầu ra tiêu chuẩn. Sau đó, nó chuyển qua chương trình tee sẽ gửi đầu vào tiêu chuẩn của nó đến đầu ra tiêu chuẩn của nó (như cat) và cũng vào tệp. Vì vậy, nó kết hợp hai luồng (lỗi và đầu ra), sau đó xuất nó đến thiết bị đầu cuối và tệp.

Điểm mấu chốt là cái đầu tiên gửi stderr/stdout đến tệp, trong khi dòng thứ hai gửi nó tới cả hai tệp và đầu ra tiêu chuẩn (is = = có lẽ thiết bị đầu cuối trừ khi bạn ở trong một cấu trúc khác đã chuyển hướng đầu ra tiêu chuẩn).

Tôi đề cập đến khả năng cuối cùng bởi vì bạn có thể có những thứ như:

(echo hello | tee xyzzy.txt) >plugh.txt

nơi không có gì kết thúc trên thiết bị đầu cuối.

24
user14408

Lệnh đầu tiên sẽ thực hiện một nhiệm vụ khác:

Sau

2>&1 > output.log 

sTDOUT cũ sẽ được lưu (sao chép) trong STDERR và sau đó STDOUT sẽ được chuyển hướng đến tệp.

Vì vậy, stdout sẽ đi đến tập tin và stderr sẽ vào giao diện điều khiển.

Và trong

 2>&1 | tee output.log

cả hai luồng sẽ được chuyển hướng đến tee. Tee sẽ sao chép mọi đầu vào vào thiết bị xuất chuẩn của nó (bảng điều khiển trong trường hợp của bạn) và để tập tin (output.log).

Và có một hình thức khác đầu tiên:

    > output.log  2>&1

điều này sẽ chuyển hướng cả STDOUT và STDERR vào tệp.

8
osgx

Các đầu ra trước đây chỉ vào tập tin. Cái thứ hai xuất cả hai vào tệp cho màn hình.

4
André Caron

Lý giải cho việc 2>&1 | tee là để có thể chụp cả thiết bị xuất chuẩn và thiết bị xuất chuẩn vào tệp nhật ký và để xem nó trên màn hình cùng một lúc. Điều này có thể được thực hiện như >output.txt 2>&1 & tail -f cũng vậy, nhưng bạn sẽ không biết khi nào lệnh nền được kết thúc - chương trình đã kết thúc hay nó đang chạy mà không có đầu ra. Các 2>&1 | tee là một thành ngữ phổ biến cho các lập trình viên.

4
Arcege

Trước tiên hãy xem một số mã mẫu :

#include <stdio.h>
main() 
{
// message 1, on stdout (using  printf)
printf("%s",          "message 1, on stdout (using  printf)\n");

// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");

// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}

Hãy so sánh kết quả :
[.__.] ./helloerror
[.__.] + tệp: không có tin nhắn; bảng điều khiển: tin nhắn 1,2,3;

./helloerror >error.txt
[.__.] + tệp: tin nhắn 1,2; bảng điều khiển: tin nhắn 3;

./helloerror 2>&1 >error.txt
[.__.] + tệp: tin nhắn 1,2; bảng điều khiển: tin nhắn 3;
[.___.] + giống như ./helloerror> error.txt

./helloerror >error.txt 2>&1
[.__.] + tệp: tin nhắn 3,1,2; bàn điều khiển: không có tin nhắn;
[.__.] + lưu ý thứ tự 3 là đầu tiên, sau đó là 1, sau đó là 2

./helloerror | tee error.txt 2>&1
[.__.] + tệp: tin nhắn 1,2; bảng điều khiển: tin nhắn 3,1,2;
[.__.] + lưu ý thứ tự 3 là đầu tiên, sau đó là 1, sau đó là 2

./helloerror 2>&1 | tee error.txt
[.__.] + tệp: tin nhắn 3,1,2; bảng điều khiển: tin nhắn 3,1,2;

Để sử dụng :
[.__.] ./helloerror >error.txt 2>&1
[.__.] -> nếu ai đó muốn tất cả các thông báo (stdout + stderr) trong tệp, nhưng không phải pinted trên bảng điều khiển

./helloerror 2>&1 | tee error.txt
[.__.] -> nếu ai đó muốn tất cả các thông báo (stdout + stderr) trong tệp và được in trên bảng điều khiển

0
Hari Perev