Как я могу полностью регистрировать все действия bash-скриптов?


45

Я хочу захватить ВСЕ данные журналов, как с сообщениями об ошибках, из вывода моего скрипта, так и перенаправить их все в файл журнала.

У меня есть скрипт, как показано ниже:

#!/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

Я хочу видеть все действия в файле /home/scripts/cron/logs

Но я вижу только то, что ставлю после команды echo.

Как проверить в логах, была ли команда SSH успешной?

Мне нужно собрать все данные журналов. Мне нужно это, чтобы отслеживать результат каждой команды в моем скрипте, чтобы лучше анализировать, что происходит, когда скрипт не работает.


Вы также можете использовать «скрипт» для выполнения этого. Смотрите этот пост: [здесь] [1] [1]: stackoverflow.com/questions/5985060/…
— xX0v0Xx

Вы должны быть осторожны с errexit - я заметил, что он игнорируется или ошибка не выходит из сценария, например. если у вас есть что-то подобное в скрипте: команда || dosmthg при сбое команды скрипт не завершает работу сразу с установленным значением errexit, а просто запускает dosmthg и продолжает скрипт

Ответы:


68

Я обычно помещаю нечто похожее на следующее в начале каждого скрипта (особенно, если он будет работать как демон):

#!/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':

Объяснение:

  1. exec 3>&1 4>&2

    Сохраняет файловые дескрипторы, чтобы их можно было восстановить до того состояния, в котором они находились до перенаправления, или использовать себя для вывода того, чем они были до следующего перенаправления.

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

    Восстановите файловые дескрипторы для определенных сигналов. Обычно не требуется, поскольку они должны быть восстановлены при выходе из суб-оболочки.

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

    Перенаправить stdoutв файл, log.outзатем перенаправить stderrв stdout. Обратите внимание, что порядок важен, когда вы хотите, чтобы они шли к одному и тому же файлу. stdout должен быть перенаправлен до stderrперенаправления на stdout.

С этого момента, чтобы увидеть вывод на консоль (возможно), вы можете просто перенаправить на &3. Например,

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

будет идти туда, куда stdoutбыло направлено, предположительно в консоль, до выполнения строки 3 выше.


<< niceroot, спасибо! Я добавил эти пути (exec, trap, exec) в начале скрипта и смог получить как stdout, так и stderr. Но одна проблема: я видел «Файловый дескриптор 3 (труба: XXX) просочился в some_command» ... Пожалуйста, дайте мне знать, как мне избежать этих ошибок. Я использовал sh на основе busybox в пользовательской плате.
— Кумар

3
Отличный кунг-фу здесь !!! - Еще лучше использовать trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Псевдосигспец RETURN восстанавливает дескрипторы файлов каждый раз, когда выполняется функция оболочки или сценарий, выполняемый с помощью. или встроенные функции источника заканчивают выполняться. Для этого (и по другим причинам) в моих сценариях я добавляю в качестве последних двух строк: return& exit 0- Просто мои 2 цента, слава вам @nicerobot!
— DavAlPi

Существует большое количество подробностей о регистрации сценариев оболочки через глобальные переменные оболочки. Мы можем эмулировать аналогичный тип ведения журнала в сценарии оболочки: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html В этом посте подробно рассматриваются вводимые уровни журналов, такие как INFO, DEBUG, ERROR. Отслеживание таких деталей, как запись скрипта, выход скрипта, запись функции, выход из функции.
— Пиюш Чордия

Перечень trapсигналов выглядит немного странно. Обычно вы также хотите включить 15.
— tripleee

1
Исправление ссылки @PiyushChordia: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html
— vigilancer

14

чтобы получить вывод ssh в ваш лог-файл, вы должны перенаправить stderrна stdout. Вы можете сделать это, добавив 2>&1после своего сценария bash.

это должно выглядеть так:

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

когда это не отображает сообщения в правильном порядке, попробуйте добавить еще одну подоболочку:

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

1
Это прекрасно работает. На самом деле вы можете направить как stdout, так и stderr с помощью:( ... ) |& tee output.log
— Noam Manos

13

Когда я читаю ваш вопрос, вы не хотите регистрировать вывод, но всю последовательность команд, в этом случае другие ответы вам не помогут.

Вызвать сценарии оболочки с -x для вывода всего:

sh -x foo.sh

Войдите в файл, который вы хотите с:

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


2
+1 для опции -x
— Coc

10

В bash вы можете поместить, set -xи он будет распечатывать каждую команду, которую он выполняет (и переменные bash) после этого. Вы можете отключить его с помощью set +x.

Если вы хотите быть параноиком, вы можете вставить set -o errexitсвой сценарий. Это означает, что сценарий завершится ошибкой и остановится, если одна команда вернула ненулевой код завершения, который является стандартным способом Unix, чтобы сообщить, что что-то пошло не так.

Если вы хотите получить более хорошие журналы, вы должны смотреть на tsв moreutilsпакете Debian / Ubuntu. Это будет префикс каждой строки с отметкой времени и распечатает ее. Таким образом, вы можете видеть, когда что-то происходит.


1
«set -o errexit» должно быть таким же, как «set -e»
— Аджит Энтони

0

После от того , что говорили другие, набор ручной является хорошим ресурсом. Я кладу:

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

В верхней части сценариев я хочу продолжать работу или, set -exесли это произойдет, в случае ошибки.


Как это поможет для логов ssh и успешного выполнения команды?
— асктяги

Тестируя фиктивный скрипт OP, он записывает каждую команду и любой результат: тайм-аут ssh, неверный домен и т. Д. Или для действительного адреса ssh он записывает команды в удаленной оболочке. Возможно, если потребуется дополнительная информация о входе в систему через ssh ssh -vv?
— dragon951
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.