Linux ít hành vi và stderr


11

Tôi đang xem đầu ra của lệnh phức tạp của tôi với less, vấn đề là stderrbị mất. stderrdòng thường được liệt kê giữa stdoutcác dòng bên trong less. Tôi muốn chúng được in ra bàn điều khiển, và khi tôi thoát ra less, để thấy chúng ở đó cùng nhau.

Tôi nhận ra có thể không có giải pháp cho vấn đề này, tôi đã đọc về teemultiteekhông có may mắn cho đến nay.


2
Bạn đang nói với tôi làm thế nào để chuyển hướng stderr sang thiết bị xuất chuẩn nhưng đó không phải là điều tôi muốn. Tôi không muốn stderr trộn với thiết bị xuất chuẩn bên trong ít hơn. Tôi muốn stderr ở trong terminal khi tôi thoát ít hơn.

Nếu stderrđược chuyển hướng đến stdout, tất cả đầu ra stderr sẽ được trộn với đầu ra bình thường stdout. Đường ống mà đầu ra lesssẽ hiển thị cả hai.
Một số lập trình viên anh chàng

Nếu tôi bỏ qua "stderr ở trong thiết bị đầu cuối khi tôi thoát ít hơn", tôi khuyên bạn nên nhấn Ctrl-L lessđể sơn lại màn hình.
kamae

Câu trả lời:


10

Có lẽ

command 2> command.err | less; cat command.err; rm command.err

Phụ lục

Dưới đây là một cách làm rõ cho những người bỏ bê việc đọc kỹ câu hỏi và những người không đọc bình luận làm rõ của OP ở trên.

haelix chỉ ra:

dòng stderr thường được liệt kê giữa các dòng stdout bên trong ít hơn

và, trong một bình luận cho những người trả lời sớm, đã viết:

Bạn đang nói với tôi làm thế nào để chuyển hướng stderr sang thiết bị xuất chuẩn nhưng đó không phải là điều tôi muốn. Tôi không muốn stderr trộn với thiết bị xuất chuẩn bên trong ít hơn. Tôi muốn stderr ở trong terminal khi tôi thoát ít hơn

Vấn đề có lẽ là nền tảng cụ thể, nó chắc chắn là điều tôi đã trải nghiệm trên các nền tảng Unix SVR4 cũ hơn.

Nếu, trên các nền tảng như vậy, bạn làm một cái gì đó như

 find / ... | less

bất kỳ thông báo lỗi nào (ví dụ như quyền thư mục) xuất hiện như thế này trong ít hơn

 stdout line 1
 stdout line 2
 error message text
 stdout line 4

để các dòng đầu ra bị che khuất bởi các thông báo lỗi.

Nếu bạn làm mới trang, các dòng đầu ra được hiển thị chính xác nhưng bạn sẽ mất các thông báo lỗi. Khi bạn thoát ít hơn, màn hình sẽ bị xóa trừ dấu nhắc lệnh.

Nếu bạn làm một cái gì đó như

  find / ... 2>&1 | less

Các thông báo lỗi được xen kẽ với đầu ra tiêu chuẩn. Một lần nữa khi bạn thoát ít hơn, màn hình trống rỗng.

Nếu trước tiên bạn chỉ muốn kiểm tra lại đầu ra tiêu chuẩn, sau đó xem các thông báo lỗi sau khi thoát ít hơn, bạn cần một giải pháp khác.

Đó là những gì tôi đã đề nghị trong câu trả lời hai dòng gốc của mình.


Đây là rác. Câu trả lời của Joachim nên được chấp nhận.
Mặt Vanilla

2
@VanillaFace: Tôi đã thêm một số tài liệu làm rõ vào câu trả lời của tôi.
RedGrittyBrick

15

Bạn phải chuyển hướng stderrđến stdout:

$ ./somecommad 2>&1 | less

Kiểm tra hướng dẫn cho bạn vỏ (ví dụ man bash.)


1
Nhận xét cho độc giả mới của câu hỏi cũ này (không dành riêng cho Joachim) Đây là những gì mọi người nghĩ khi quét câu hỏi đầu tiên. Nhưng vấn đề tinh tế hơn - xem thảo luận trong các bình luận sau câu trả lời của dmckee
RedGrittyBrick

1

chỉ cần nói shell để chuyển hướng fd 2 đến fd 1 (stderr đến stdout)

 make 2>&1 | less

1

Một điều còn thiếu từ tất cả các câu trả lời cho đến nay là lý do, tại sao điều này lại xảy ra. Vấn đề ở đây là một số loại điều kiện chạy đua giữa quá trình xuất nội dung đến stderrlesshiển thị đầu ra từ stdouttrên thiết bị đầu cuối. Nếu lessbắt đầu hiển thị sau khi tất cả đầu ra stderrđã được in đến thiết bị đầu cuối, thì nó lesssẽ giữ nguyên điều đó và bạn có thể thấy các thông báo sau khi thoát less. OTOH nếu lessđã bắt đầu hiển thị nội dung, sau đó thông báo lỗi xen kẽ với lessđầu ra và không có gì được giữ lại sau khi lessthoát (vì lesschỉ bảo toàn thiết bị đầu cuối như trước khi bắt đầu và không biết gì về thông báo lỗi ở giữa).

Bạn có thể thấy điều đó một cách dễ dàng, nếu bạn làm ví dụ

grep foo -r /etc | less

Tất cả các thông báo lỗi "Quyền bị từ chối" trộn lẫn với lessđầu ra và sẽ không có gì sau khi bạn thoát. Nếu bạn làm

grep foo -r /etc | (sleep 10; less)

tất cả (hoặc ít nhất là) các thông báo lỗi đã được in đến thiết bị đầu cuối trước khi lesscó cơ hội hiển thị đầu ra và bạn sẽ thấy các thông báo lỗi sau đó.

Tất nhiên, bạn thường không muốn đợi 10 giây trước khi bắt đầu less, nhưng với Linux, bạn cũng có thể cung cấp các giá trị phân đoạn cho thời gian chờ và với các quy trình chạy nhanh thường là một cái gì đó sleep 0.1đủ để tránh điều kiện cuộc đua. (Nhưng, tất nhiên, nếu bạn muốn hoặc phải ở bên thực sự an toàn, hãy sử dụng giải pháp của RedGrittyBrick).


0

Bạn cần hiểu khái niệm "mô tả tập tin". Thông thường, một ứng dụng unix sẽ bắt đầu với ba mô tả tệp đặc biệt:

  • Đầu vào tiêu chuẩn
  • Sản lượng tiêu chuẩn
  • Lỗi tiêu chuẩn

"Ống" |trong vỏ kết nối stdouttừ một quá trình với quá trình stdintiếp theo.

Lỗi là - theo thiết kế - không được cung cấp cho stdinquá trình tiếp theo. Chúng thường sẽ không có ý nghĩa với ứng dụng tiếp theo và không nên bị ẩn khỏi người dùng.

Nếu bạn muốn trộn các lỗi vào thiết bị xuất chuẩn, bạn có thể sử dụng 2>&1, ví dụ , về cơ bản là "nối stderr vào thiết bị xuất chuẩn". Ví dụ

find /etc 2>&1 | less

cũng nên bao gồm đầu ra lỗi từ các tập tin không thể truy cập.

find /etc 2>&1 >/dev/null | less

sẽ chỉ cung cấp cho bạn các lỗi.


0

Tôi bối rối về câu hỏi của bạn, theo như tôi ca nói hành vi mong muốn của bạn là mặc định.

Khi tôi sử dụng

#include <stdio.h>

int main(int argc, char**argv){
  for (int j=0; j<10; ++j){
    fprintf( (j%2 ? stdout : stderr) , "%d\n" , j);
  }
  return 0;
}

để có được một bài kiểm tra đơn giản,

$ ./testredirection | less

không chỉ những gì bạn yêu cầu. Đó là tôi thấy

1
3
5
7
9
(END) 

trong less

$ ./testredirection | less
0
2
4
6
8
$ 

khi tôi nghỉ việc less


Thật lạ nhưng mọi thứ không phải lúc nào cũng như thế này. Thử với một tập lệnh ( echo info ; echo error 1>&2) và lặp lại thử nghiệm: cả hai dòng được dẫn đến ít hơn.
cYrus

@cYrus: Điều đó cũng làm việc như tôi mong đợi. 'Khóa học tôi đã thử trên hộp Mac OS. Bash 3.2.17, ít hơn 394. Có thể một cái gì đó cụ thể linux. Trong mọi trường hợp, cách tiếp cận của RedGrittyBrick sẽ hoạt động tốt.
dmckee --- ex-moderator mèo con

Kỳ dị! Debian Bóp / Bash 4.1.5 / Ít hơn 436
cYrus

Vâng, tôi đã mở một hộp Khoa học Linux 5.3 tại nơi làm việc và có hành vi mong đợi với bash 3.0.15 và ít hơn 382. Có thể có hồi quy trong đó không?
dmckee --- ex-moderator mèo con

Tôi không biết, tôi nghĩ đó chỉ là vấn đề đệm.
cYrus

0

Tôi tình cờ gặp vấn đề này ở một trong những bản Debian 5.0 của tôi gần đây. ví dụ: ls abc | Tôi ít thấy rằng thông báo lỗi đi vào ít hơn, điều này trái với kiến ​​thức của tôi.

Sau một số lần thử, tôi thấy rằng nó chỉ là một cái gì đó liên quan đến bộ đệm màn hình. stderr KHÔNG đi vào thực tế ít hơn. Bạn có thể sử dụng các phím mũi tên Lên hoặc Xuống (hoặc j / k) để thể hiện.

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.