Як я можу повністю зафіксувати всі дії сценаріїв bash?


44

Я хочу захопити ВСІ дані журналів, як із повідомленнями про помилки, з мого виводу скрипту, і перенаправити їх усіх на файл журналу.

У мене є сценарій, як нижче:

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

Але я бачу лише це, що я ставлю після команди ехо.

Як перевірити журнали, чи вдала команда SSH?

Мені потрібно зібрати всі дані журналів. Мені потрібно це для моніторингу результатів кожної команди в моєму сценарії, щоб краще проаналізувати, що відбувається, поки сценарій не працює.


Ви також можете використовувати "скрипт" для цього. Дивіться цей пост: [тут] [1] [1]: stackoverflow.com/questions/5985060 / ...
xX0v0Xx

Ви повинні бути обережними з errexit - я помітив, що це ігнорується або помилка не виходить із сценарію, наприклад. якщо у вас є щось подібне в скрипті: command || dosmthg, коли команда не спрацьовує, скрипт не виходить негайно з набором errexit, а просто запускає dosmthg і продовжує сценарій

Відповіді:


67

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

#!/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" ... Будь ласка, дайте мені знати, як я можу уникнути отримання цих помилок. Я використовую shushbox sh sh в користувацькій дошці.
кумар

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також.
трійка

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"
Ajith Antony

0

Виходячи з сказаного іншими, цей посібник є хорошим ресурсом. Я кладу:

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

У верхній частині сценаріїв я хочу продовжувати роботу, або set -exякщо вона повинна вийти після помилки.


Як це допоможе для журналів ssh та успішного виконання команди?
asktyagi

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