W powłoce systemu Unix mam plik env (plik env definiuje parametry wymagane do uruchomienia skryptu użytkownika, takie jak nazwa pliku dziennika i ścieżka, przekierowuje wyjścia i błędy do pliku dziennika, szczegóły połączenia z bazą danych itp. ), Który przekierowuje wszystkie wyjścia ( komunikaty echo ) i błędy do pliku dziennika z wykonywanego skryptu przy użyciu następującego kodu:
exec 1>>${LOG_FILE}
exec 2>>${LOG_FILE}
Plik env jest wykonywany na początku każdego skryptu. Ze względu na powyższy kod w pliku env, wszystkie wyjścia konsoli, które mogą być wyjściami użytkownika lub błędami, są bezpośrednio wyprowadzane do pliku dziennika, którego faktycznie potrzebowałem.
Ale jest kilka wybranych wyników użytkownika, które chcę, aby były wyświetlane zarówno w konsoli, jak iw pliku dziennika. Ale z powodu powyższego kodu nie jestem w stanie tego zrobić.
Wiem, że jeśli usunę powyższy kod, mogę uzyskać pożądany wynik w tym przypadku, ale będę musiał ręcznie zapisać wszystkie inne wyniki do pliku dziennika, co nie jest łatwym zadaniem.
Czy istnieje sposób, aby uzyskać dane wyjściowe zarówno w konsoli, jak i pliku dziennika bez usuwania powyższych kodów?
/dev/fd/3
to nazwa pliku, która odnosi się do "aktualnie otwartego fd 3", więctee /dev/fd/3
zapisze wszystko, co pojawia się na jego stdin, do fd 1, a także fd 3 (/dev/fd/3
plik). Fd 1 jest podłączony do pliku dziennika, fd 3 jest podłączony do konsoli.echo "blah" | tee file1.txt | tee file2.txt >/dev/null
„Blah” nie zostanie umieszczony w plik1.txt i plik2.txt, ale nie zostanie zapisany w konsoli.tee
, który z kolei zapisuje do terminala), zamiast przechodzić bezpośrednio do terminala, i dostosowują swoje wyjście, aby pasowało.Tak, chcesz użyć
tee
:Po prostu prześlij polecenie do tee i przekaż plik jako argument, na przykład:
Spowoduje to wydrukowanie danych wyjściowych do STDOUT i zapisanie tych samych danych wyjściowych w pliku dziennika. Zobacz,
man tee
aby uzyskać więcej informacji.Zauważ, że to nie zapisze stderr do pliku dziennika, więc jeśli chcesz połączyć dwa strumienie, użyj:
źródło
script.sh: line 5: exec: 1: not found
Wypróbowałem odpowiedź joonty'ego, ale dostałem też
błąd. To, co działa najlepiej dla mnie ( potwierdzone, że działa również w zsh):
Plik /tmp/both.log zawiera następnie
Dziennik /tmp/both.log jest dołączany, chyba że usuniesz -a z tee.
Wskazówka:
>(...)
jest substytucją procesu. To pozwalaexec
natee
polecenia tak, jakby był to plik.źródło
exec > >(tee ${LOG_FILE}) 2>&1
.Chciałem wyświetlić logi na stdout i plik dziennika wraz ze znacznikiem czasu. Żadna z powyższych odpowiedzi nie zadziałała dla mnie. Skorzystałem z podstawiania procesu i polecenia exec i wymyśliłem następujący kod. Przykładowe dzienniki:
Dodaj następujące wiersze u góry skryptu:
Mam nadzieję, że to komuś pomoże!
źródło
w przypadku pliku dziennika możesz wprowadzić datę do danych tekstowych. poniższy kod może pomóc
ouput: 2. Plik dziennika zostanie utworzony przy pierwszym uruchomieniu i będzie aktualizowany od następnych uruchomień. W przypadku braku pliku dziennika w przyszłości skrypt utworzy nowy plik dziennika.
źródło
Znalazłem sposób na uzyskanie pożądanego wyniku. Choć może to być nieco nieortodoksyjny sposób. Tak czy inaczej, to idzie. W pliku redir.env mam następujący kod:
Następnie w rzeczywistym skrypcie mam następujące kody:
Tutaj echo wyprowadza tylko do konsoli, dane wyjściowe dziennika tylko do pliku dziennika, a wyjścia komunikatów do pliku dziennika i konsoli.
Po wykonaniu powyższego pliku skryptu mam następujące wyjścia:
W konsoli
Dla pliku dziennika
Mam nadzieję, że to pomoże.
źródło
Spróbuj tego, zadziała:
źródło
exec > >(tee -a ${log_file} )
działa idealny dla moich potrzeb. Poprzednie rozwiązania powyżej przerywałyby części mojego skryptu, które wymuszałyby wyjście, gdyby zawiodły. Dziękujęźródło
Uważam, że bardzo przydatne jest dołączanie zarówno stdout, jak i stderr do pliku dziennika. Byłem zadowolony, widząc rozwiązanie alfonx z
exec > >(tee -a)
, ponieważ zastanawiałem się, jak to zrobić za pomocąexec
. Natrafiłem na kreatywne rozwiązanie wykorzystujące składnię here-doc i.
: /unix/80707/how-to-output-text-to-both-screen-and-file-inside-a-shell -scenariuszOdkryłem, że w zsh rozwiązanie here-doc można zmodyfikować za pomocą konstrukcji „multios” w celu skopiowania danych wyjściowych zarówno do stdout / stderr, jak i do pliku dziennika:
Nie jest tak czytelny jak
exec
rozwiązanie, ale ma tę zaletę, że pozwala na zalogowanie tylko części skryptu. Oczywiście, jeśli pominiesz EOF, cały skrypt zostanie wykonany z logowaniem. Nie jestem pewien, jakzsh
implementuje multio, ale może to mieć mniejszy narzut niżtee
. Niestety wydaje się, że nie można używać multio zexec
.źródło