Mettez un texte devant chaque nouvelle ligne qu'un programme imprime sur stdout


9

Je veux donc faire un peu de journalisation et pour cela, je veux mettre une date devant la sortie d'un script bash. Le problème est qu'il a plusieurs lignes de sortie. Je peux seulement mettre la date avant la sortie entière. Mais alors j'ai une ligne sans date dans les journaux. Bien sûr, je peux supposer que la date de la ligne ci-dessus est la même, mais j'espérais qu'il existe une solution. Merci d'avance!

Voici mon script qui appelle un autre script:

#!/bin/sh
echo $(date "+%F %T") : starting script
echo $(date "+%F %T") : $(./script.sh)
echo $(date "+%F %T") :script ended

Voici la sortie:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
second line of output
2012-07-26 15:35:17 : script ended

Et c'est ce que j'aimerais avoir:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
2012-07-26 15:35:15 : second line of output
2012-07-26 15:35:17 : script ended

Je ne suppose pas que vous puissiez simplement changer le deuxième script?
jmetz

Non, malheureusement non. Voilà pourquoi je suis venu ici.
tzippy

Réponses:




2

Vous pouvez utiliser awk

./script.sh | awk '{ print d,$1}' "d=$(date "+%F %T")"

awkprend un flux d'entrée et modifie sa sortie. Ce script indique "imprimer d suivi de la sortie d'origine", puis remplit davec la date.


1
Cela n'évalue-t-il pas l' dateexpression une seule fois également, de sorte que toutes ces lignes s'impriment en même temps?
Daniel Beck

@DanielBeck Oui, c'est vrai - j'avais supposé que c'était la date à chaque fois, mais je venais de terminer mon test assez rapidement
Paul

1

Cela imprimera la date et l'heure actuelles avant chaque ligne de sortie de ./script.sh:

set -f
./script.sh | while read -r LINE; do echo $(date "+%F %T") : "$LINE"; done
set +f

Comment ça fonctionne

  • set -fdésactive l'expansion bash (ou echo *n'imprime pas un véritable astérisque).

  • while read -r LINE; do ... doneenregistre une ligne de sortie dans la variable $LINEet s'exécute ...jusqu'à ce que toutes les lignes soient traitées.

  • echo $ (date "+% F% T"): "$ LINE" imprime la ligne avec l'heure et la date actuelles.

  • set +f active l'expansion bash, de sorte qu'elle n'interfère pas avec le reste de votre script bash.


Il n'est évalué qu'une seule fois, donc chaque sedinsère la même date, juste avant de démarrer le deuxième script. Probablement pas ce que l'utilisateur veut ...
Daniel Beck

Je ne pense pas que cette tentative fonctionnera non plus. AFAIK, le sous-shell entier est évalué complètement en premier, puis la boucle est parcourue. Alors maintenant, les temps sont postérieurs à l'exécution.
Daniel Beck

Votre exemple ne fonctionne pas, car vous retardez uniquement la sortie, pas l'exécution de ls. Essayez simplement votre script avec ce qui suit script.sh: #!/bin/bash(nouvelle ligne)echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4
Daniel Beck

À utiliser readavec une whileboucle au lieu d'une boucle for.
chepner

@chepner: Bonne idée.
Dennis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.