Linux mniej zachowań i stderr

11

Patrzę na wynik mojego skomplikowanego polecenia less, problem polega na tym, że stderrsię gubię. stderrlinie zwykle są wymienione pomiędzy stdoutliniami wewnątrz less. Chciałbym, aby były wydrukowane na konsoli, a kiedy wychodzę less, aby zobaczyć je tam razem.

Zdaję sobie sprawę, że może nie być rozwiązaniem tego, czytałem o tee, a multiteejednak nie ma szczęścia do tej pory.

haelix
źródło
2
Mówisz mi, jak przekierować stderr na standardowe wyjście, ale nie tego chciałem. Nie chcę, aby stderr pomieszał się ze stdout w środku mniej. Chciałbym, aby stderr był w terminalu, kiedy opuszczam mniej.
Jeśli stderrzostanie przekierowany stdout, wszystkie dane wyjściowe stderr zostaną zmiksowane z włączonym normalnym wyjściem stdout. Pipingowanie tego wyjścia lesspokaże oba.
Jakiś programista koleś
Jeśli zignoruję „stderr, aby być w terminalu, gdy wychodzę mniej”, sugeruję nacisnąć Ctrl-L w, lessaby odmalować ekran.
kamae

Odpowiedzi:

10

Może

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

Uzupełnienie

Poniżej znajduje się wyjaśnienie dla ludzi, którzy zaniedbują uważne przeczytanie pytania i którzy nie przeczytali powyższego komentarza PO.

haelix wskazał:

linie stderr zwykle pojawiają się pomiędzy liniami stdout wewnątrz mniej

i w komentarzu do wczesnych odpowiedzi odpowiedział:

Mówisz mi, jak przekierować stderr na standardowe wyjście, ale nie tego chciałem. Nie chcę, aby stderr pomieszał się ze stdout w środku mniej. Chciałbym, aby stderr był w terminalu, kiedy opuszczam mniej

Problem prawdopodobnie dotyczy konkretnej platformy, z pewnością jest to coś, czego doświadczyłem na starszych platformach Unix SVR4.

Jeśli na takich platformach robisz coś takiego

 find / ... | less

wszelkie komunikaty o błędach (np. uprawnienia do katalogu) wyglądają mniej więcej tak

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

tak że linie wyjściowe są zasłonięte komunikatami o błędach.

Jeśli odświeżysz stronę, linie wyjściowe są wyświetlane poprawnie, ale tracisz komunikaty o błędach. Gdy wyjdziesz mniej, ekran zostanie wyczyszczony, z wyjątkiem wiersza polecenia.

Jeśli zrobisz coś takiego

  find / ... 2>&1 | less

Komunikaty o błędach są mieszane ze standardowym wyjściem. Ponownie, gdy wyjdziesz mniej, ekran jest pusty.

Jeśli chcesz najpierw przejrzeć tylko standardowe wyjście w mniej, a następnie zobaczyć komunikaty o błędach po mniejszym wyjściu, potrzebujesz innego rozwiązania.

Właśnie to sugerowałem wstępnie w mojej oryginalnej, dwuwierszowej odpowiedzi.

RedGrittyBrick
źródło
To śmieci Odpowiedź Joachima powinna zostać zaakceptowana.
Vanilla Face
2
@VanillaFace: Do mojej odpowiedzi dodałem trochę materiału wyjaśniającego.
RedGrittyBrick
16

Musisz przekierować stderrdo stdout:

$ ./somecommad 2>&1 | less

Sprawdź instrukcję dla siebie powłoki (np man bash.)

Jakiś koleś programisty
źródło
1
Komentarz dla nowych czytelników tego starego pytania (nie dotyczy to w szczególności Joachima) Tak myślą wszyscy na pierwszy skan pytania. Ale problem jest bardziej subtelny - patrz dyskusja w komentarzach po odpowiedzi
dmckee
Skrót dla 2> i 1 to | & . Można to zatem uprościć jako$ ./somecommad |& less
Melvin Abraham
1

po prostu powiedz powłoce, aby przekierowała fd 2 na fd 1 (stderr na stdout)

 make 2>&1 | less
jackdoe
źródło
1

Jedną z brakujących dotychczas odpowiedzi jest powód, dla którego tak się dzieje. Problemem jest tutaj pewien rodzaj wyścigu między procesem wysyłania danych do stderri lesswyświetlaniem danych wyjściowych z stdoutterminala. Jeśli lesszacznie się wyświetlać po wydrukowaniu wszystkich danych wyjściowych do stderrterminala, lesszachowa to i po wyjściu zobaczysz komunikaty less. OTOH, jeśli lessjuż zaczął wyświetlać rzeczy, to komunikaty o błędach mieszają się z lesswyjściem i nic nie jest zachowywane po lesswyjściu (ponieważ lesspo prostu zachowuje terminal tak, jak był przed uruchomieniem i nie wie nic o komunikatach o błędach, które pojawiły się pomiędzy).

Możesz to łatwo zobaczyć, jeśli np

grep foo -r /etc | less

Wszystkie komunikaty o błędach „Odmowa zezwolenia” mieszają się z danymi lesswyjściowymi i po wyjściu nic nie będzie. Jeśli zrobisz

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

wszystkie (lub przynajmniej większość) komunikatów o błędach zostały wydrukowane na terminalu, zanim lesspojawi się szansa na wyświetlenie danych wyjściowych, a następnie zobaczysz komunikaty o błędach.

Oczywiście zwykle nie chcesz czekać 10 sekund przed rozpoczęciem less, ale w Linuksie możesz również podać wartości ułamkowe dla czasu oczekiwania, a przy szybkich procesach często sleep 0.1wystarczy tak mało , aby uniknąć wyścigu. (Ale oczywiście, jeśli chcesz lub musisz być po naprawdę bezpiecznej stronie, skorzystaj z rozwiązania RedGrittyBrick).

Elmar Zander
źródło
0

Musisz zrozumieć pojęcie „deskryptorów plików”. Zwykle aplikacja unixowa uruchamia się z trzema specjalnymi deskryptorami plików:

  • Standardowe wejście
  • Standardowa moc wyjściowa
  • Standardowy błąd

„Rura” |w powłoce łączy się stdoutz jednego procesu z drugim stdin.

Błędy - z założenia - nie są stdinuwzględniane w następnym procesie. Często nie będą miały sensu w następnej aplikacji i nie powinny być ukryte przed użytkownikiem.

Jeśli chcesz mieszać błędy w standardowe wyjście, możesz użyć np. 2>&1, Który mówi w zasadzie „dołącz stderr do standardowego”. Na przykład

find /etc 2>&1 | less

powinien również zawierać wyjście błędu z niedostępnych plików.

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

poda tylko błędy.

Ma ZAKOŃCZENIE - Anony-Mus
źródło
0

Jestem zdezorientowany co do twojego pytania, o ile mogę powiedzieć, że twoje pożądane zachowanie jest domyślne.

Kiedy używam

#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;
}

uzyskać prosty test,

$ ./testredirection | less

robi tylko to, o co prosisz. To widzę

1
3
5
7
9
(END) 

w lessi

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

kiedy odejdę less

dmckee --- były kot moderator
źródło
To dziwne, ale nie zawsze tak jest. Spróbuj użyć skryptu ( echo info ; echo error 1>&2) i powtórz test: obie linie są potokowane do mniejszej.
cyr
@cYrus: To też działa zgodnie z oczekiwaniami. „Oczywiście, że próbowałem na komputerze Mac OS. Bash 3.2.17, mniej 394. Może coś specyficznego dla Linuksa. W każdym razie podejście RedGrittyBrick powinno działać dobrze.
dmckee --- były moderator kociak
Dziwne! Debian Squeeze / Bash 4.1.5 / Less 436
cYrus
Tak, otworzyłem w pracy powłokę Naukowego Linuxa 5.3 i uzyskałem oczekiwane zachowanie w wersji bash 3.0.15 i mniejszej 382. Czy może tam być regresja?
dmckee --- były moderator kociak
Nie wiem, myślę, że to tylko kwestia buforowania.
cyr
0

Zdarza mi się ostatnio spotkać ten problem w jednym z moich Debianów 5.0. na przykład ls abc | mniej uważam, że komunikat o błędzie przechodzi w mniej, co wbrew mojej wiedzy.

Po kilku próbach odkryłem, że jest to po prostu coś związanego z buforami ekranowymi. stderr tak naprawdę NIE wchodzi w mniej. Do demonstracji możesz użyć klawiszy strzałek w górę lub w dół (lub j / k).

Jagoda
źródło