Jak przekierować stderr i stdout do różnych plików, a także wyświetlać je w terminalu?


30

Chcę zobaczyć wynik polecenia w terminalu, jak gdyby nie było przekierowania. Ponadto stderr musi zostać przekierowany do err.log, a stdout musi zostać przekierowany do stdout.log.

Byłoby miło mieć również dokładną kopię tego, co jest wyświetlane w terminalu, tj. Błędy drukowane jako i kiedy występują, w osobnym pliku: stdouterr.log.


@Nuno Nie, to nie jest. OP chce mieć różne pliki dla stdout i stderr.
dogbane

@dogbane Tak, masz rację. Przepraszam za to.
Nuno C. Inácio,

Wciąż uważam to pytanie za bardzo znajome. Spójrzmy w górę ... Oto bardzo podobny unix.stackexchange.com/q/4195/250 , a oto pokrewny unix.stackexchange.com/q/1416/250
phunehehe

Odpowiedzi:


37

Użyj teepolecenia w następujący sposób:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 jest jak zamieniasz stderr i stdout, ponieważ tee może zaakceptować tylko stdout.

Spójrz na uniksowe polecenie tee, aby uzyskać bardziej zaawansowane przekierowania tee.


fajne rozwiązanie. Czy jest jakiś sposób na uzyskanie kodu wyjścia cmd?
turbanoff,

2
@turbanoff Wymień cmdz (cmd ; echo >exit_code.txt $?).
Parthian Shot

Uważam, że to powinno lepiej zachować kolejność rzeczy wypisywanych do wiersza poleceń:((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log)
TTT,

5

Myślę, że zalogowanie stdout i stderr do dwóch różnych plików to świetny pomysł. Czy to nie czyni dzienników asynchronicznymi? Więc wypróbowałem następujące:

  • stdout do „stdout.log” (zgodnie z sugestią dogbane)
  • stderror do „stderr.log” (jak sugeruje dogbane)
  • wszystkie dane wyjściowe do „all.log” i
  • nadal mogę zobaczyć dane wyjściowe na wyświetlaczu (choć w osobnym terminalu!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

w innym terminalu

tail -f --sleep-interval=2 all.log

Czy nie jest możliwe skierowanie stderr bezpośrednio do drugiego tty? W takim przypadku nie jest wymagany plik dziennika.
Steven Lu

@StevenLu tak, jeśli znasz nazwę i masz pozwolenie na napisanie do drugiego tty, które można zrobić.
Jasen

1
łatwiej byłoby &| tee all.logna końcu polecenia zamiast&> all.log
Jasen

@Jasen: 2. raz widzę &|. Rozumiem &>, |&też, ale co to &|znaczy w tym kontekście? Nie mogłem znaleźć odpowiedniego odwołania do składni, nie w sieci, nawet nie przeglądając strony podręcznika bash „bash (1)” ... Tx
Cbhihe

1
@Chihihe, o ile mogę powiedzieć, że nic nie robi, chciałem powiedzieć|&
Jasen

3

@dogbane, Thanks.
Znalazłem też inny sposób, który zapisuje oba strumienie w przybliżeniu w kolejności, w jakiej byłyby drukowane bez przekierowania.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

Ale działa to tylko z powłokami, które obsługują podstawianie procesów.


-2

Spróbuj tego :

command 2>&1 | tee bothLog

4
Witaj vasile, to nie odpowiada na pytanie: balki potrzebuje osobnych plików dla stdout i stderr, twoje rozwiązanie miksowałoby oba w tym samym strumieniu.
Mat.

Dlaczego ludzie łączą stdout i stderr razem? Lub powiedz innym, żeby to zrobili?
nurettin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.