Stellen Sie vor jede neue Zeile, die ein Programm auf stdout druckt, einen Text


9

Ich möchte also ein wenig protokollieren und dafür ein Datum vor die Ausgabe eines Bash-Skripts setzen. Das Problem ist, dass es mehrere Ausgabezeilen gibt. Ich kann nur das Datum vor die gesamte Ausgabe setzen. Aber dann habe ich eine Zeile ohne Datum in den Protokollen. Natürlich kann ich davon ausgehen, dass das Datum in der obigen Zeile das gleiche ist, aber ich hatte gehofft, dass es eine Lösung gibt. Danke im Voraus!

Dies ist mein Skript, das ein anderes Skript aufruft:

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

Dies ist die Ausgabe:

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

Und das hätte ich gerne:

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

Ich nehme nicht an, dass Sie einfach das zweite Skript ändern könnten?
Jmetz

Nein, leider nicht. Deshalb bin ich hergekommen.
Zippy

Antworten:


9

Laut einer ähnlichen Frage zu Stack Overflow gibt es zwei großartige Optionen.

awk ( Antwort )

<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'

kommentieren ( Antwort )

annotate ist ein kleines Bash-Skript, das entweder direkt über den hier angegebenen Link oder auf Debian-basierten Systemen über das Paket devscripts(in Form von annotate-output) abgerufen werden kann .



2

Sie können verwenden awk

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

awkNimmt einen Eingabestream und ändert seine Ausgabe. Dieses Skript sagt "print d gefolgt von der Originalausgabe" und füllt dann dmit dem Datum.


1
Wertet dies den dateAusdruck nicht auch nur einmal aus, so dass alle diese Zeilen zur gleichen Zeit gedruckt werden?
Daniel Beck

@DanielBeck Ja, das stimmt - ich hatte angenommen, dass es jedes Mal das Datum aufnimmt, aber meinen Test gerade schnell genug beendet
Paul

1

Dies wird das aktuelle Datum und die aktuelle Uhrzeit vor jeder Ausgabezeile von ./script.sh:

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

Wie es funktioniert

  • set -fDeaktiviert die Bash-Erweiterung (oder echo *druckt keinen Stern).

  • while read -r LINE; do ... doneSpeichert eine Ausgabezeile in der Variablen $LINEund wird ausgeführt ..., bis alle Zeilen verarbeitet wurden.

  • echo $ (Datum "+% F% T"): "$ LINE" druckt die Zeile mit der aktuellen Uhrzeit und dem aktuellen Datum.

  • set +f Schaltet die Bash-Erweiterung wieder ein, damit der Rest Ihres Bash-Skripts nicht beeinträchtigt wird.


Es wird nur einmal ausgewertet, daher sedfügt jeder das gleiche Datum ein, unmittelbar bevor das zweite Skript gestartet wird. Wahrscheinlich nicht das, was der Benutzer will ...
Daniel Beck

Ich denke nicht, dass dieser Versuch auch funktionieren wird. AFAIK, die ganze Subshell wird zuerst komplett ausgewertet, dann wird die Schleife durchlaufen. Also jetzt sind die Zeiten von nach der Hinrichtung.
Daniel Beck

Ihr Beispiel funktioniert nicht, da Sie nur die Ausgabe verzögern, nicht die Ausführung von ls. Probieren Sie Ihr Skript einfach mit folgendem Code aus script.sh: #!/bin/bash(newline)echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4
Daniel Beck

Verwenden Sie readmit einer whileSchleife anstelle einer for-Schleife.
Chepner

@chepner: Gute Idee.
Dennis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.