Как я могу полностью регистрировать все действия 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 успешной?

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

Bluemark
источник
Вы также можете использовать «скрипт» для выполнения этого. Смотрите этот пост: [здесь] [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 выше.

nicerobot
источник
<< 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если это произойдет, в случае ошибки.

dragon951
источник
Как это поможет для логов ssh и успешного выполнения команды?
асктяги
Тестируя фиктивный скрипт OP, он записывает каждую команду и любой результат: тайм-аут ssh, неверный домен и т. Д. Или для действительного адреса ssh он записывает команды в удаленной оболочке. Возможно, если потребуется дополнительная информация о входе в систему через ssh ssh -vv?
dragon951