Comment enregistrer complètement toutes les actions de scripts bash?

45

Je veux capturer TOUTES les données des journaux, à la fois avec des messages d'erreur, à partir de la sortie de mon script et les rediriger vers un fichier journal.

J'ai un script comme ci-dessous:

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

Je veux voir toutes les actions dans le fichier /home/scripts/cron/logs

Mais je ne vois que ce que je mets après la commande echo.

Comment vérifier les journaux si la commande SSH a réussi?

J'ai besoin de rassembler toutes les données de journaux. J'ai besoin de cela pour surveiller le résultat de chaque commande de mon script, afin de mieux analyser ce qui se passe lorsque le script échoue.

BlueMark
la source
Vous pouvez également utiliser le "script" pour effectuer cela. Voir cet article: [ici] [1] [1]: stackoverflow.com/questions/5985060/…
xX0v0Xx
vous devez être prudent avec errexit - j'ai remarqué qu'il est ignoré ou qu'une erreur ne quitte pas le script, par exemple. si vous avez quelque chose comme ceci dans le script: commande || dosmthg lorsque la commande échoue, le script ne se ferme pas immédiatement avec errexit, mais lance simplement dosmthg et poursuit le script

Réponses:

68

Je mets généralement quelque chose de similaire au suivant au début de chaque script (surtout s'il fonctionnera en tant que démon):

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

Explication:

  1. exec 3>&1 4>&2

    Enregistre les descripteurs de fichier afin qu’ils puissent être restaurés sur ce qu’ils étaient avant la redirection ou utilisés eux-mêmes pour une sortie sur ce qu’ils étaient avant la redirection suivante.

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

    Restaurez les descripteurs de fichier pour des signaux particuliers. Généralement non nécessaire car ils doivent être restaurés à la sortie du sous-shell.

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

    Rediriger stdoutvers un fichier log.outpuis rediriger stderrvers stdout. Notez que l'ordre est important lorsque vous voulez qu'ils soient dans le même fichier. stdout doit être redirigé avant d' stderrêtre redirigé vers stdout.

A partir de là, pour voir la sortie sur la console (peut-être), vous pouvez simplement rediriger vers &3. Par exemple,

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

ira à l’endroit où a stdoutété dirigé, probablement la console, avant d’exécuter la ligne 3 ci-dessus.

Nicerobot
la source
<< niceroot, merci! J'ai ajouté ces trois lignes (exec, trap, exec) au début du script et je peux obtenir stdout et stdout. Mais un problème: j'ai vu "un descripteur de fichier 3 (pipe: XXX) filtré sur une_commande" ... Merci de me dire comment éviter ces erreurs. J'utilise busybox sh basé dans le tableau personnalisé.
Kumar
3
Super KungFu ici !!! - Encore mieux est d'utiliser trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Les descripteurs de fichier de restauration de pseudo sigspec RETURN à chaque fois qu'une fonction shell ou un script est exécuté avec le script. ou les sources intégrées se terminent. Pour cela (et pour d’autres raisons), dans mes scripts, j’ajoute les deux dernières lignes: return& exit 0- Seulement mes 2 cents, bravo à @nicerobot!
DavAlPi
Il existe une bonne quantité de détails sur la journalisation des scripts shell via des variantes globales de shell. Nous pouvons émuler le même type de journalisation dans le script shell: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html La publication contient des détails sur l’introduction de niveaux de journalisation tels que INFO, DEBUG, ERROR. Détails de traçage tels que l'entrée de script, la sortie de script, l'entrée de fonction, la sortie de fonction.
Piyush Chordia
L'énumération des trapsignaux semble légèrement bizarre. Habituellement, vous voudrez également inclure 15.
tripleee
14

pour obtenir la sortie ssh dans votre fichier journal, vous devez rediriger stderrvers stdout. vous pouvez le faire en ajoutant 2>&1après votre script bash.

ça devrait ressembler à ça:

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

si cela n’affiche pas les messages dans le bon ordre, essayez d’ajouter un autre sous-shell:

#!/bin/bash
((
...
) 2>&1) | tee ...
Christian
la source
1
Cela fonctionne très bien. En fait, vous pouvez diriger stdout et stderr avec:( ... ) |& tee output.log
Noam Manos
13

En lisant votre question, vous ne voulez pas enregistrer la sortie, mais toute la séquence de commandes, auquel cas les autres réponses ne vous aideront pas.

Appelez les scripts shell avec -x pour tout afficher:

sh -x foo.sh

Connectez-vous au fichier que vous voulez avec:

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

Alex Holst
la source
2
+1 pour l'option -x
Coc le
10

Dans bash, vous pouvez mettre set -xet il imprimera toutes les commandes qu'il exécute (et les variables bash) par la suite. Vous pouvez l'éteindre avec set +x.

Si vous voulez être paranoïaque, vous pouvez mettre set -o errexitdans votre script. Cela signifie que le script échouera et s'arrêtera si une commande renvoyait un code de sortie non nul, qui est le moyen standard Unix de signaler que quelque chose s'est mal passé.

Si vous voulez obtenir de meilleurs journaux, vous devriez regarder tsdans le moreutilspaquet debian / ubuntu. Il préfixera chaque ligne avec un horodatage et l’imprimera. Ainsi, vous pouvez voir quand les choses se passaient.

Rory
la source
1
"set -o errexit" doit être la même chose que "set -e"
Ajith Antony
0

Pour faire suite à ce que d’autres ont dit, le manuel d’ installation est une bonne ressource. Je mets:

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

Au sommet des scripts, je souhaite continuer, ou set -exs'il doit se fermer en cas d'erreur.

dragon951
la source
Comment cela aidera-t-il les journaux ssh et l'exécution réussie de la commande?
asktyagi le
En testant avec le script factice de l'OP, il enregistre chaque commande et quel que soit le résultat obtenu: délai d'attente ssh, domaine incorrect, etc. Ou pour une adresse ssh valide, il enregistre les commandes dans le shell distant. Si plus d'informations sur les connexions ssh sont nécessaires, peut ssh -vv- être ?
dragon951