bash: ustaw -x loguje do pliku

18

Mam skrypt powłoki, set -xaby mieć pełne wyjście / debugowanie:

#!/bin/bash

set -x
command1
command2
...

Dane wyjściowe wyglądają następująco:

+ command1
whatever output from command1
+ command2
whatever output from command2

Moim problemem jest to, wyjście shell (spowodowane przez set -x) idzie do stderr, zmieszanej z wyjściem poleceń ( command1, command2...). Byłbym szczęśliwy, gdyby „normalne” wyjście na ekranie (jak skrypt działał bez niego set -x) i „dodatkowe” wyjście bash oddzielnie w pliku.

Więc chciałbym mieć to na ekranie:

whatever output from command1
whatever output from command2

a to w pliku dziennika:

+ command1
+ command2

(również dobrze, jeśli plik dziennika zawiera wszystko razem)

set -x 2> fileOczywiście doens't podjąć właściwą efekt, bo to nie jest wyjście z polecenia set, ale to się zmieni zachowanie bash.

Używanie bash 2> filecałego skryptu również nie działa dobrze, ponieważ przekierowuje stderr każdego polecenia, które również działają w tej powłoce, więc nie widzę komunikatu o błędzie poleceń.

redseven
źródło
2
Moje google-fu wydaje się być dziś silne: wyślij bash -x wyjście do pliku dziennika bez przerywania standardowego wyjścia
steeldriver

Odpowiedzi:

20

Na podstawie tej odpowiedzi ServerFault Wyślij wyjście bash -x do pliku dziennika bez przerywania standardowego wyjścia , nowoczesne wersje bash zawierają BASH_XTRACEFDspecjalnie do określania alternatywnego deskryptora pliku dla wyjściaset -x

Na przykład możesz to zrobić

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

wysłać dane wyjściowe set -xdo plikulogfile , zachowując standardowe standardowe dane wyjściowe i standardowe strumienie błędów dla następujących poleceń.

Zauważ, że użycie fd 19 jest arbitralne - musi to być tylko dostępny deskryptor (tzn. Nie 0, 1, 2 lub inny numer, który już przypisałeś).

steeldriver
źródło
Rzeczywiście zapisuje dziennik śledzenia bash osobno, jednak naprawdę trudno jest odczytać 2 wyjścia (stdout + stderr na ekranie i ślad bash w plikach dziennika), ponieważ są one całkowicie niezsynchronizowane. Zobacz rozwiązanie, które właśnie opublikowałem .
ponownie
4

Po ponad roku znalazłem właściwe rozwiązanie, aby mieć zarówno „normalne” wyjście (stdout + stderr - ślad bash) na ekranie, jak i wszystkie razem (stdout + stderr + ślad bash) w pliku (bash.log) :

exec   > >(tee -ia bash.log)
exec  2> >(tee -ia bash.log >& 2)
exec 19> bash.log

export BASH_XTRACEFD="19"
set -x

command1
command2
redseven
źródło
To tylko kombinacja odpowiedzi steeldrivera i tej .
jarno
3

Steeldriver dał ci jedno podejście. Alternatywnie możesz po prostu przekierować STDERR do pliku:

script.sh 2> logfile

Oznacza to jednak, że zarówno dane wyjściowe utworzone przez set -xopcję, jak i wszelkie inne wygenerowane komunikaty o błędach trafią do pliku. Rozwiązanie Steeldriver przekieruje tylko set -xwyjście, które prawdopodobnie jest tym, czego chcesz.

terdon
źródło
„... zarówno dane wyjściowe utworzone za pomocą opcji set -x, jak i wszelkie inne wygenerowane komunikaty o błędach trafią do pliku.” I dlatego dla mnie to nie działa. Moim głównym problemem jest to, że nie widzę łatwo „prawdziwych błędów”, ponieważ wszystkie te dane wyjściowe bashu trafiają do stderr. Przekierowanie komunikatów o błędach poleceń ukryłoby również „prawdziwe błędy” w inny sposób.
redseven
@ redseven Obawiam się, że to, o co prosisz, nie jest jasne. Czy możesz edytować swoje pytanie i wyjaśnić? Staraj się unikać używania terminu „wyjście” do wszystkiego, co nie będzie standardowe. Czy chcesz oddzielić i) normalne wyjście; ii) jakieś błędy zgłoszone przez twoje polecenie i iii) ustawić -x? Czy więc odpowiedź steeldrivera nie wystarczy? Jeśli nie, pokaż nam prosty skrypt, który możemy skopiować, i powiedz nam, jak chcesz się zachowywać.
terdon
@steeldriver już doskonale odpowiedział na pytanie.
redseven
@redseven ah, to super. Ponieważ twój komentarz przyszedł o wiele później, myślałem, że nadal czegoś potrzebujesz i nie mogłem zobaczyć, jak odpowiedź steeldriver nie rozwiązała twojego problemu. Cieszę się, że to wszystko jest uporządkowane.
terdon