Jak mogę w pełni zalogować wszystkie działania skryptów bash?


44

Chcę przechwycić WSZYSTKIE dane z dzienników, zarówno z komunikatami o błędach, z danych wyjściowych skryptu i przekierować je wszystkie do pliku dziennika.

Mam skrypt jak poniżej:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

Chcę zobaczyć wszystkie działania w pliku /home/scripts/cron/logs

Ale widzę tylko to, co wstawiłem po poleceniu echa.

Jak sprawdzić w dziennikach, czy polecenie SSH zakończyło się pomyślnie?

Muszę zebrać wszystkie dane z dzienników. Potrzebuję tego, aby monitorować wynik każdego polecenia w moim skrypcie, aby lepiej analizować, co się dzieje, gdy skrypt nie działa.


Aby to zrobić, możesz również użyć „skryptu”. Zobacz ten post: [tutaj] [1] [1]: stackoverflow.com/questions/5985060/…
— xX0v0Xx

musisz być ostrożny z errexit - zauważyłem, że jest ignorowany lub błąd nie wychodzi ze skryptu np. jeśli masz coś takiego w skrypcie: polecenie || dosmthg gdy komenda nie skrypt nie wyjść natychmiast z zestawem errexit ale wystarczy uruchomić dosmthg i kontynuuje skryptu

Odpowiedzi:


67

Ogólnie na początku każdego skryptu umieszczam coś podobnego do następującego (zwłaszcza jeśli będzie działał jako demon):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Wyjaśnienie:

  1. exec 3>&1 4>&2

    Zapisuje deskryptory plików, aby można je było przywrócić do tego, czym były przed przekierowaniem, lub wykorzystać je do wyprowadzenia tego, co było przed następnym przekierowaniem.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Przywróć deskryptory plików dla określonych sygnałów. Nie jest to na ogół konieczne, ponieważ należy je przywrócić po wyjściu podpowłoki.

  3. exec 1>log.out 2>&1

    Przekieruj stdoutdo pliku, log.outa następnie przekieruj stderrdo stdout. Pamiętaj, że kolejność jest ważna, gdy chcesz, aby trafiły do ​​tego samego pliku. stdout musi zostać przekierowany, zanim stderrzostanie przekierowany do stdout.

Odtąd, aby zobaczyć dane wyjściowe na konsoli (być może), możesz po prostu przekierować na &3. Na przykład,

echo "$(date) : part 1 - start" >&3

pójdzie tam, gdzie stdoutzostał skierowany, prawdopodobnie na konsolę, przed wykonaniem linii 3 powyżej.


<< niceroot, dzięki! Dodałem te trzy linie (exec, trap, exec) na początku skryptu i jestem w stanie uzyskać zarówno stdout, jak i stderr. Ale jeden problem: widziałem „Wyciekły deskryptor pliku 3 (potok: XXX) na komendę some_” ... Daj mi znać, jak mogę uniknąć tych błędów. Używam sh w oparciu o busybox w niestandardowej płycie.
— kumar

3
Świetne KungFu tutaj !!! - Jeszcze lepiej jest używać trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Pseudo sigspec RETURN deskryptory plików przywracają za każdym razem, gdy funkcja powłoki lub skrypt są wykonywane przy pomocy. lub wbudowane źródła kończą wykonywanie. Z tego (i innych powodów) w moich skryptach dodaję jako ostatnie 2 wiersze: return& exit 0- Tylko moje 2 centy, wyrazy uznania dla ciebie @nicerobot!
— DavAlPi

Istnieje wiele szczegółowych informacji na temat rejestrowania skryptów powłoki za pomocą globalnych zmiennych powłoki. Możemy emulować podobny rodzaj logowania w skrypcie powłoki: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html Post zawiera szczegółowe informacje na temat wprowadzania poziomów dziennika, takich jak INFO, DEBUG, BŁĄD. Szczegóły śledzenia, takie jak wpis skryptu, wyjście skryptu, wejście funkcji, wyjście funkcji.
— Piyush Chordia

Wyliczenie trapsygnałów wygląda nieco dziwnie. Zwykle też chcesz to uwzględnić 15.
— tripleee


14

aby uzyskać wyjście ssh do twojego pliku dziennika, musisz przekierować stderrna stdout. możesz to zrobić, dołączając 2>&1po skrypcie bash.

To powinno wyglądać tak:

#!/bin/bash
(
...
) 2>&1 | tee ...

gdy to nie wyświetla wiadomości w odpowiedniej kolejności, spróbuj dodać kolejną podpowłokę:

#!/bin/bash
((
...
) 2>&1) | tee ...

1
To działa świetnie. W rzeczywistości możesz reżyserować stdout i stderr za pomocą:( ... ) |& tee output.log
— Noam Manos

13

Kiedy czytam twoje pytanie, nie chcesz rejestrować danych wyjściowych, ale cała sekwencja poleceń, w którym to przypadku inne odpowiedzi ci nie pomogą.

Wywołaj skrypty powłoki z opcją -x, aby wyświetlić wszystko:

sh -x foo.sh

Zaloguj się do pliku, który chcesz:

sh -x foo.sh >> /home/scripts/cron/logs


2
+1 za opcję -x
— Coc

10

W bash możesz umieścić, set -xa następnie wydrukuje każde wykonane polecenie (i zmienne bash). Możesz to wyłączyć za pomocą set +x.

Jeśli chcesz być paranoikiem, możesz wpisać set -o errexitswój skrypt. Oznacza to, że skrypt zawiedzie i zatrzyma się, jeśli jedno polecenie zwróci niezerowy kod wyjścia, co jest standardowym sposobem uniksowym sygnalizującym, że coś poszło nie tak.

Jeśli chcesz uzyskać ładniejszy dzienników, należy spojrzeć tsw moreutilspakiecie debian / ubuntu. Poprzedzi każdą linię znacznikiem czasu i wydrukuje ją. Możesz więc zobaczyć, kiedy coś się działo.


1
„set -o errexit” musi być tym samym, co „set -e”
— Ajith Antony

0

Zgodnie z tym, co powiedzieli inni, zestaw instrukcji jest dobrym źródłem. Włożyłem:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

Na górze skryptów chcę kontynuować, lub set -exjeśli powinien zakończyć się po błędzie.


Jak to pomoże dziennikom ssh i pomyślnemu wykonaniu polecenia?
— asktyagi

Testując za pomocą fałszywego skryptu OP, rejestruje każde polecenie i bez względu na wynik: limit czasu ssh, niepoprawna domena itp. Lub dla prawidłowego adresu ssh zapisuje polecenia w zdalnej powłoce. Jeśli potrzebujesz więcej informacji na temat logowania ssh ssh -vv?
— dragon951
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.