hiển thị STDOUT trước STDERR?


9

Tôi mới làm quen với bash và tôi không thể tìm ra cách chạy một lệnh nhất định, giả sử ./fffvà in các thiết bị xuất chuẩn thông thường trước stderr (Bản thân tôi bối rối về ý nghĩa của nó)

ví dụ

$ printf "I am a\ndrill\n" > fff; 
$ cat fff nofile fff nofile fff

I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill

cần in như:

I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory

Tôi hiểu rằng trước tiên tôi cần chuyển hướng đầu ra của mình sang một tệp và sau đó thêm lỗi vào cùng một tệp tuy nhiên đây là đầu ra tôi nhận được cho

$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see 

I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory

2
Đã catthực sự thay thế "a" bằng "một số"?
Dmitry Grigoryev

oh dang tôi có thể đã làm rối chuỗi. Tôi sẽ sửa nó ngay lập tức @DmitryGrigoryev
Meow

Câu trả lời:


18

Bạn sẽ cần phải giữ đầu ra stderr ở đâu đó để có thể hiển thị nó ở cuối.

Một tập tin đến với tâm trí:

fff 2> file; cat file >&2

Hoặc bộ nhớ (ở đây sử dụng spongetừ moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: trong {...}mô tả tệp (fd) 3 điểm cho cùng một tài nguyên với thiết bị xuất chuẩn ban đầu (vì vậy chúng tôi có thể sử dụng nó để khôi phục thiết bị xuất chuẩn cho fff).
  • fff <redirs> | sponge <redirs>, fffspongebắt đầu đồng thời (với <redirs>áp dụng một cách độc lập) với fff's stdout đi đến một đường ống, và sponge' s stdin là đầu kia của ống.
  • 2>&1: fd 2 của fff(stderr) trỏ đến điều tương tự như trên 1: đường ống tại điểm này, do đó fff, lỗi xảy ra spongethông qua đường ống đó.
  • >&3: now stdout trỏ đến thiết bị xuất chuẩn ban đầu (chuyển hướng trở lại như cũ)
  • 3>&-: chúng tôi đóng fd 2 mà fffkhông cần
  • spongetích lũy đầu vào của nó và chỉ hiển thị nó (trên thiết bị xuất chuẩn của nó đã được chuyển hướng >&2đến cùng một tài nguyên như stderr) sau khi nó đã phát hiện ra eof trên stdin của nó (giả sử là khi fffchấm dứt và đã ghi tất cả đầu ra của nó trên thiết bị xuất chuẩn của nó).

Nếu spongekhông được cài đặt, bạn có thể thay thế nó bằng perl -0777 -pe ''. Với -pe '', perlđọc một bản ghi tại một thời điểm từ đầu vào của nó và ghi nó trên thiết bị xuất chuẩn. -0777là chế độ slurp trong đó bản ghi (chỉ một trong trường hợp đó) là toàn bộ đầu vào.


Xin vui lòng phá vỡ nó nếu bạn có thời gian!
George Udosen

Chúng ta có thể sử dụng teethay vì sponge...?
George Vasiliou

@GeorgeUdosen xem chỉnh sửa.
Stéphane Chazelas

1
@GeorgeVasiliou, teekhông giữ dữ liệu, nó viết nó ngay khi đọc nó.
Stéphane Chazelas

2
@MeOw: Điều đó tốt, nhưng, như dòng thứ ba trong câu trả lời của Stéphane cho thấy, bạn không cần phải lưu thiết bị xuất chuẩn; chỉ cần làm cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt. (Và bạn có thể không muốn sử dụng >>.) Ngoài ra, Stéphane đưa ra điểm tuyệt vời mà bạn có lẽ nên làm cat ferr.txt >&2để viết thông tin stderr vào stderr.
G-Man nói 'Phục hồi Monica'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.