ubuntuusers.de

exitcode + log

Status: Gelöst | Ubuntu-Version: Lubuntu 16.04 (Xenial Xerus)
Antworten |

frank-w

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Hallo,

ich versuche in einem Script den Exitcode auszuwerten und gleichzeitig mit zu loggen.

1
2
RET=1
make && RET=0 #könnte auch RET=$? nehmen, geht aber primär nur darum, ob make erfolgreich war

soweit funktioniert es mit dem Returncode

nun möchte ich aber die Ausgabe von make mitloggen, ohne auf zusätzliche Programme zu setzen, welche erst installiert werden müssten wie z.b. screen

1
2
3
4
make 2>&1 | tee $LOGFILE #so landet die Ausgabe komplett im logfile
make 2>&1 | tee $LOGFILE && RET=0 #ret ist immer 0 da von tee überschrieben
make 2>&1 && RET=0 | tee $LOGFILE #logfile ist leer
(make && export RET=0) 2>&1 | tee $LOGFILE #funktioniert leider auch nicht

hat jemand eine Idee?

Gruß Frank

redknight Team-Icon

Moderator & Supporter
Avatar von redknight

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 21857

Wohnort: Lorchhausen im schönen Rheingau

Warum nutzt Du tee?

1
(make 2>&1) >$LOGFILE

müsste eigentlich reichen. Dann kannst Du auch den Exitcode hinterher auslesen 😉

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Damit ich die Ausgabe parallel auf dem Bildschirm sehe...die log ist zum leichteren suchen der Fehler...

redknight Team-Icon

Moderator & Supporter
Avatar von redknight

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 21857

Wohnort: Lorchhausen im schönen Rheingau

Ich hab keine Ahnung, wie man das ordentlich/richtig macht. Ich würde make ordentlich loggen lassen und das log mit

tail -f

mitlesen. Aber vllt hat ja noch jemand eine sinvollere Idee.

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

mir ist von make kein Parameter bekannt,der das mitloggen ermöglicht...nur die Ausgabe-Umleitung der bash. selbst wenn ich tail nutze muss ich ein separates Terminal nutzen (bei remote-zugriff nicht so toll),da ich sonst wieder die Problematik mit der exitcode habe.

Aktuell nutze ich ja screen -L als Workaround,setzt aber vorraus,das screen installiert ist und dort gibts das Problem,dass sich screen nach dem make beendet und die Ausgabe ist auch weg.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Das was Du vorhast, geht nicht mit einer normalen Pipe, der Rückgabewert wird dabei ja von dem von tee verdeckt.

ABER ... Du kannst den "Nebenprozess" (sprich: das tee) in eine Process Substitution auslagern, dann funktioniert es:

1
make 2> >( tee "$logfile" ) ; echo $?

(beachte bitte: eigene Variablen immer $klein, denn $GROSS sind Systemvariablen, und die willst Du ja nicht aus Versehen kaputtschreiben.)

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

track schrieb:

Das was Du vorhast, geht nicht mit einer normalen Pipe, der Rückgabewert wird dabei ja von dem von tee verdeckt.

Mit einer Named Pipe geht es. Allerdings ist das deutlich umständlicher als Dein Ansatz:

ABER ... Du kannst den "Nebenprozess" (sprich: das tee) in eine Process Substitution auslagern, dann funktioniert es:

1
make 2> >( tee "$logfile" ) ; echo $?

Wenn man noch mehr Ausgaben mitschneiden möchte, kann man auch einfach einen größeren Block von Befehlen unter der Ausgabeumleitung ausführen:

1
2
3
4
5
6
{
  if make ... 2>&1 ; then
    make install 2>&1
    echo "alles fertig"
  fi
} | tee logfile

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Danke euch beiden, das mit der "Process Substitution" funktioniert super. besonders nett ist, dass man alle Meldungen sieht, und nur die Fehler in der Log landen ☺

das andere probiere ich bei Gelegenheit aus. kann man innerhalb der {} eine Variable setzen und außerhalb nutzen?

1
2
3
{
  make 2>&1 && make install 2>&1 && RET=0
} | tee $logfile

kann man da auch alles anzeigen und nur stderr in die log schreiben?

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

*Push* kann jemand bitte die beiden Fragen noch beantworten?

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

frank-w schrieb:

kann man innerhalb der {} eine Variable setzen und außerhalb nutzen?

1
2
3
{
  make 2>&1 && make install 2>&1 && RET=0
} | tee $logfile

Theoretisch ja:

{
    foo=bar
}
echo "$foo"

Gibt „bar“ aus.

Durch die Pipe wird aber der Compound Command vorne eben doch wieder in einer Subshell ausgeführt und deine Variable geht hinterher verloren:

{
    foo2=bar
} | /bin/true
echo "$foo2"

Leere Ausgabe.

kann man da auch alles anzeigen und nur stderr in die log schreiben?

Fällt mir nichts Knuffiges ein, was nicht auf die bereits genannten Lösungen hinauslaufen oder deutlich komplizierter sein würde.

Vielleicht ist das Array „$PIPESTATUS“ für dich noch interessant:

#!/bin/bash

example_command()
{
    echo output on stdout
    echo output on stderr >&2
    return 42
}

example_command | tee logfile-stdout
echo ${PIPESTATUS[0]} ${PIPESTATUS[1]}

example_command 3>&1 1>&2 2>&3 | tee logfile-stderr
echo ${PIPESTATUS[0]} ${PIPESTATUS[1]}

example_command 2>&1 | tee logfile-both
echo ${PIPESTATUS[0]} ${PIPESTATUS[1]}

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Hallo, es darf ruhig auf die vorherige Lösung aufbauen. Ich möchte nur möglichst nicht bei jeder zeile die Prozess Subst neu machen.

1
2
3
make 2> >( tee "$logfile" ) &&
make modules 2> >>( tee "$logfile" ) &&
... && RET=1

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Wenn es ums Wiederverwenden geht, könntest du die Process Substitution einmalig am Anfang machen und am Ende schließen:

#!/bin/bash

exec 3> >(tee logfile)

make alpha 2>&3 &&
make bravo 2>&3 &&
make charlie 2>&3 && success=1

exec 3>&-

Musst zwar immer noch jedes Mal angeben, was mit stderr passieren soll, ist aber vermutlich einfacher. ☺

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

cool, das sieht ja schonmal super aus und wesentlich übersichtlicher 😉 wieviele neue file-descriptoren (heißen doch so, oder) kann man eigentlich anlegen (also die 3 in dem letzten Beispiel)?

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Ganze Menge.

$ ulimit -n
1024

Das ist bei mir der Default, der sich aber einstellen lässt – auch pro Anwendung. Bei manchen sehr großen Anwendungen ist es auch notwendig, dass man das nach oben hin korrigiert. Für Systemdienste gibt es dafür bei systemd die Option LimitNOFILE.

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Danke euch

Antworten |