# Fortschrittsanzeige bei ebuild Emerge

## Finswimmer

Hi!

Ich weiß nicht, wie es euch geht.

Aber hier mein Beispiel:

Hab vor einer halben Std. ein emerge angeworfen, und nun will ich ins Bett.

Ich möchte eigentlich nicht den emerge unterbrechen. Bin faul, klar könnte ich das über ebuild path/to/ebuild/ emerge machen...

Darum gehts aber nicht  :Wink: 

So...

Klar ist, dass man nicht sagen kann, wielange so ein emerge geht, außer man hat das betreffende Paket schon installiert (genlop -t Paket)

Aber:

Man könnte doch eigentlich einen Counter mitlaufen lassen, wieviele Unterverzeichnisse bearbeitet worden sind, und wieviele noch fehlen.

Das hätte doch den Vorteil, dass man nicht abbricht, wenn man sieht, dass der Compiler schon bei 89/90 Unterverzeichnissen ist.

Dass damit noch lange nicht gesagt ist, wielange das letzte Verzeichnis + make install + merge dauert, ist klar.

Aber es wäre doch schonmal ein Anhaltspunkt...

Was haltet ihr davon?

Könnte man das realisieren?

Bin gespannt auf eure Ideen.

Tobi

----------

## Anarcho

Klar, schreib nen Patch für make! Die werden sich sicher freuen!

Aber eine Lösung für das indirekte Problem hätte ich für dich:

Wenn du ins Bett willst, einfach im emerge-Fenster STRG-Z drücken,

dann einfach mit  

```
fg && halt
```

 fortfahren falls du eventuelle Fehlermeldungen sehen willst am nächsten morgen,

sonst 

```
fg; halt
```

Dann fährt der Rechner nach dem emerge runter.

Oder mit Log 

```
fg > /root/merge.log 2>&1; halt
```

 oder du guckst danach in /var/log/emerge.log nach.

----------

## Finswimmer

*gg* 

Ja, das mit dem Patch könnte sich als etwas schwierig gestalten.

Gibt es denn in jedem dieser Unterverzeichnisse eine Makefile?

Dann könnte man einfach alle Makefile zusammenzählen:

find|grep Makefile|grep -v ".am"|grep -v ".in"|wc|gawk -F " " '{ print $1 }'

Und nun müsste ich doch "nur" ne Funktion einbauen, die sobald eine Makefile geöffnet wird, einen Counter hochsetzt.

Andere Idee:

Ist es so, dass jede Makefile, nachdem sie bearbeitet worden ist, "anders" aussieht?

Sprich: Wie mergt Emerge, wenn ich make abbreche, und wieder starte, was schon kompiliert worden ist?

Damit müsste ich doch auch gut arbeiten können?

Dann wäre es noch einfacher:

1) find|grep Makefile|grep -v ".am"|grep -v ".in"|wc|gawk -F " " '{ print $1 }'

--> gibt die Gesamtanzahl aus

2) Suche nach abgearbeiteten Makefiles

--> Statusanzeige (Abgearbeitete Makefiles / Gesamtanzahl)

Das dann in ein Script, was automatisch alle 10 Sek aufgerufen wird, oder immer sobald ein Unterverzeichnis gewechselt wird...

Könnt ja mal schreiben, ob das zu umständlich ist.

Gruß

Tobi

----------

## l3u

Wenn du was abbrichst, dann fängt emerge wieder von vorne an. Du kannst allerdings ccache benutzen, dann benutzt der Compiler beim mehrfachen Kompilieren der selben Datei mit den selben Parametern eine schonmal kompilierte Datei, die er aus dem Zwischenspeicher holt. Das beschleunigt das ganze dann merklich.

Ansonsten hab ich mir auch schonmal überlegt, ob man nicht vor dem Merge die Verzeichnisse in /tmp/xyz speichern könnt, und dann im Merge-Log des entsprechenden Pakets nach make[\d*]: Entering dirtectory ... leaving directory ... suchen könnt (damit sparst du dir anderweitige Handstände, weil da steht ja dann, sofern man das Loggen in der /etc/make.conf zuläßt, alles drin, was man auch auf dem Bildschirm zu sehen bekommt). Halt alles per Script -- damit könnt man dann sehen, welche Verzeichnisse schon bearbeitet wurden.

Inwiefern das ganze auch aussagekräftig ist, sei dahingestellt ... weil es kann ja sein, daß der Compiler im einen Verzeichnis gar nix macht und im anderen Stunden brauch ...

Aber wär doch ganz nett, oder? Dann konnt man z.B. makeprogress paket eingeben und sieht dann, wieviele Verzeichnisse zu bearbeiten sind, und wieviele noch fehlen.

Frage dazu: Wie kommt man auf die Nummer, die im Log vor dem Paket steht (z.B. "3863-inkscape-0.43.log")? Die bräucht man natürlich dazu ...

----------

## Finswimmer

Wenn ich meinen emerge Vorgang abbreche, sind alle Teile in /var/tmp/portage/PAKET enthalten.

Gehe ich da dann rein, und sage make, so kompiliert er weiter. Und auch nur das, was noch nicht kompiliert worden ist.

Das Ganze kann man mit ebuild /path/to/package/ emerge automatisieren.

Von daher ist dein Weg wohl etwas zu umständlich.

Ich will keinen Weg, der mir das abbrechen erleichtert, das, was ich beschrieben habe, ist schon gut.

Ich möchte gerne sowas, was du dir unter makeprogress vorstellst.

Daher sind meine Fragen nach der technischen Realisierung noch offen.

Die Nummer ist, soweit ich weiß der darugehörende Prozess. Denn theoretisch könntest du ja so schlau sein, und zweimal das gleiche emergen. Dann gäbe es Probleme mit der eindeutigen Zuordnung.

Gruß Tobi

----------

## Anarcho

Also das "Fortführen" der Kompilation erledigt make selber. Es schaut sich die ergebnisse an und

vergleicht das Datum mit dem Datum der Sourcen. Wenn es neuer ist als diese wird 

es nicht neu kompiliert.

----------

## mrsteven

Eigentlich könntest du für deine Zwecke auch genlop ("emerge genlop") einsetzen, z.B.:

```
emerge -uDpv world | genlop --pretend
```

Der Nachteil davon ist nur, dass genlop natürlich keine Informationen für Pakete ausspuckt, die du vorher noch nie installiert hast. Aber bei einem Systemupdate kann man so ganz gut abschätzen, wie lange es dauert.

Schön ist auch "genlop --current". Damit kannst du das Programm schätzen lassen, wie lange das aktuelle emerge ungefähr noch braucht. Leider ist das in der momentan als stabil markierten Version irgendwie kaputt (zumindest funktioniert das bei mir nicht mehr).

----------

## l3u

Daß make von selber da weitermacht, wo es aufgehört hat, weiß ich schon -- aber daß man das auch mit emerge da fortsetzen kann, wußte ich noch nicht. Naja, man lernt nie aus ;-) Nichtsdestotrotz ist ccache nicht schlecht und schadet auch nix.

genlop -c zeigt mir auch immer nur an, daß derzeit kein Programm kompiliert ...

Aber sowas wie "makeprogress" (hab ich mir einfach mal schnell so überlegt den Namen ;-) sollte ja eigentlich nicht allzu schwer zu realisieren sein. Weiß einer, was mir die Zahlen vor der Logdatei sagen wollen?

----------

## Finswimmer

@mrsteven: Das was du beschreibst ist die Gesamtdauer.

Ich möchte aber ein Programm erstellen, was den Fortschritt innerhalb eines einzigen Pakets angibt.

@Anarcho:

Du meinst, der Kompiler vergleicht die Daten. 

Er wird doch nicht jede Datei vergleichen, auf welche Datei sollte ich mich da sinnvollerweise beschränken?

Bzw.: Es muss doch eine übergeordnete Prozedur vorhanden sein, die dieses Vergleichen ausführt. Weißt du, wo die ist, denn dann müsste ich da doch meine eigene Prozedur reinschreiben...

Danke

Tobi

----------

## Anarcho

 *Finswimmer wrote:*   

> @Anarcho:
> 
> Du meinst, der Kompiler vergleicht die Daten. 

 

Nein, dann hätte ich compiler geschrieben. Wioe ich schon sagte, make untersucht die Daten anhand der Einstellungen im makefile.

Dort sollten alle Objektdateien einzeln verhandelt werden und diese werden dann mit den zugehörigen Quellen verglichen. Nur dann wird ein

bestimmtes Ziel angefahren. 

Make kann viel mehr als nur Programme übersetzen. Du kannst dir auch ein makefile für deine Diplomarbeit schreiben, 

was verschiedene tex-files abarbeitet, jenachdem ob du welche geändert hast und vieles mehr.

 *Finswimmer wrote:*   

> Er wird doch nicht jede Datei vergleichen, auf welche Datei sollte ich mich da sinnvollerweise beschränken?
> 
> Bzw.: Es muss doch eine übergeordnete Prozedur vorhanden sein, die dieses Vergleichen ausführt. Weißt du, wo die ist, denn dann müsste ich da doch meine eigene Prozedur reinschreiben...
> 
> Danke
> ...

 

Ich verstehe nicht so ganz was du meinst.

----------

## Finswimmer

Das letzte von mir war ein großer Denkfehler.

Ich dachte, dass das Ganze so abläuft:

1.Prozess überprüft Unterverzechnis auf Aktualität und ruft dann evtl make auf.

Aber da make das, wie du mir eben geschrieben hast, alles selbst erledigt, ist die Idee natürlich nicht richtig.

Und aus Versehen habe ich eben Kompiler mit make synonym verwendet. --> Noch ein Fehler  :Wink: 

Ich müsste also diese Zählprozedur, die mir vorschwebt, in make unterbringen, und genau bevor make das Verzeichnis auf das aktuelle Datum überprüft?

Tobi

----------

## l3u

Wieso willst du denn ständig zählen? Langt doch, wenn man ne Verzeichnisliste macht, und dann per Log nachschaut, welche der Verzeichnisse schon abgearbeitet wurden. Also einmal zählen per Aufruf. Das ist doch viel leichert unterzubringen als was, was das ständig überprüft

----------

## Finswimmer

Das mit dem Zählen war ja nur eine Idee, weil mir bis jetzt noch nichts Einfacheres untergekommen ist.

So sieht meine emerge.log aus:

```
1135945332:  >>> emerge (3 of 21) sys-apps/tcp-wrappers-7.6-r8 to /

1135945332:  === (3 of 21) Cleaning (sys-apps/tcp-wrappers-7.6-r8::/usr/portage/sys-apps/tcp-wrappers/tcp-wrappers-7.6-r8.ebuild)

1135945334:  === (3 of 21) Compiling/Merging (sys-apps/tcp-wrappers-7.6-r8::/usr/portage/sys-apps/tcp-wrappers/tcp-wrappers-7.6-r8.ebuild)

1135945423:  === (3 of 21) Post-Build Cleaning (sys-apps/tcp-wrappers-7.6-r8::/usr/portage/sys-apps/tcp-wrappers/tcp-wrappers-7.6-r8.ebuild)

```

Du hast weiter oben was von Debug geschrieben.

Das ist dann aber die Debug Anzeige von emerge. Wie aktiviere ich die denn?

Sobald ich dann dort mehr Infos stehen habe, werde ich deinen Vorschlag mal testen.

Danke

Tobi

----------

## l3u

Debug? Nee, ich hab nix von debug geschrieben. Du mußt lediglich z.B.

```
PORT_LOGDIR="/var/log/portage"
```

In deiner /etc/make.conf drinstehen haben dann wird alles, was während eines Merge-Vorgangs auf dem Bildschirm ausgegeben wird, in einer Logdatei gespeichert. Z.B. eben /var/log/portage/3867-encfs-1.2.4.1.log -- und das könnt man dann imo schön nach sowas wie

```
make[2]: Entering directory `/var/tmp/portage/encfs-1.2.4.1/work/encfs-1.2.4/po'

...

make[2]: Leaving directory `/var/tmp/portage/encfs-1.2.4.1/work/encfs-1.2.4/po'
```

----------

## Finswimmer

So.

Nun ists fertig.

Mir gefällts:

Hier die Ausgabe.

```

/tmp/makeprogress bluefish

Es wurden schon  2 Verzeichnisse von 6 verarbeitet

```

Man startet das Script mit dem Paketnamen als Parameter.

```
#!/bin/bash

log="/var/log/portage/"`/usr/bin/ls /var/log/portage/ | /bin/grep $1`

Verarbeitet=`cat $log | /bin/grep "make\[.\]"|/bin/grep -i leaving |wc|gawk -F " " '{ print $1 }'`

pfad="/var/tmp/portage/"`/usr/bin/ls /var/tmp/portage/|grep $1`"/work/"`/usr/bin/ls /var/tmp/portage/|grep $1`

gesamt=` /usr/bin/ls -1R $pfad |/bin/grep -i makefile|grep -v ".am" |/bin/grep -v ".in"|wc|gawk -F " " '{ print $1 }'`

echo "Es wurden schon " $Verarbeitet" Verzeichnisse von" $gesamt "verarbeitet"

```

Und nun kann ich endlich sehen, wieviele Pakete noch bearbeitet werden müssen.

Ich hoffe ich habe keinen Denkfehler gemacht, indem ich gesagt habe, dass in jedem Verzeichnis das kompiliert wird, eine Makefile liegen muss.

Danke an Libby. Mit den extra Log Dateien war es der entscheidende Tip!

Ciao

TobiLast edited by Finswimmer on Thu Jan 12, 2006 9:37 pm; edited 1 time in total

----------

## Finswimmer

Zusatz:

Es ist schlauer nach leaving zu suchen, statt nach entering.

Sonst zeigt er sobald man im letzten Verzeichnis ist, an, dass es x von x wären...und nicht x-1 von x.

Tobi

----------

## Anarcho

Ich will dich in deiner kreativen Phase nicht stoppen, aber nicht jedes Paket wird mittels make gebaut...

----------

## Finswimmer

Guter Einwand.

Was gibt es denn sonst noch für Möglichkeiten ein Paket zu bauen?

Und wie kann man die dann eventuell überprüfen?

Aber die Mehrzahl wird wohl doch mit make gemacht... Und darüber freue ich mich erstmal  :Wink: 

Ciao

Tobi

----------

## Romses

Es gab da mal ein Script, welches einfach alle .c oder .cpp Dateien gesucht hat, und die mit der Anzahl der .o Dateien verglichen hat.

AFAIK könnte man so abschätzen, wieviele Dateien man noch zu verarbeiten hat.

Leider habe ich dieses Script nicht mehr...

Gruß Romses

----------

## l3u

Also ungefähr so hatte ich mir das auch vorgestellt. Aber zu bedenken ist, daß nur nach dem Namen des Paketes zu suchen nicht zwingend auch das entsprechende Logfile liefern muß ... weil wenn du ein Paket mehrfach kompilierst, dann wird je ein Logfile angelegt. Mit dem selben Namen drin, aber einer anderen Nummer vorne dran.

----------

## Finswimmer

@Libby: Gut. Das war ja auch erstmal einfach so reingehackt in den Pc. Damit was läuft, und das kann man ja durchaus verbessern.

Hast du schon einen gewissen Überblick, was die Zahlen nun wirklich aussagen?

Zuerst dachte ich, dass das die Prozessnummer sei, aber dem ist wohl nicht so.

Findest du, denn du hast das Loggen schon länger als ich, eine Regelmäßigkeit in den Zahlen?

Oder:

Man prüft, ob es mehrere LogDateien des gleichen Pakets nimmt, und nimmt die mit dem aktuellen Datum und Zeit.

Tobi

----------

## l3u

Also ehrlich gesagt: Ich hab keine Ahnung, was die Zahlen heißen. Die sind scheinbar eine UID für das Logfile ... aber woher man wissen soll, welche Zahl das ist ... keine Ahnung ... vielleicht soltle man da mal einen aus #gentoo-devs auf freenode fragen oder so ...

----------

## Finswimmer

```
gesamt=` /usr/bin/ls -1R $pfad |/bin/grep -i makefile|grep -v ".am" |/bin/grep -v ".in"|wc|gawk -F " " '{ print $1 }'`
```

Hier tritt noch ein kleines Problem auf.

Nvu, was ich gerade baue, und immernoch nicht fertig ist, ist so groß, dass ls Argument list too long ausgibt.

Nun meine Frage, da ich mit der Bash nicht so bewandert bin:

ls * | grep schreibt erst den gesamten Inhalt des Verzeichnisses in ein Variable, und grep sucht sich dann das Richtige raus.

Klar, irgendwann läuft die Variable über.  Kann ich das irgendwie umgehen, indem ich das in einem mache?

Mit einer externen größeren Variable will ich ja nicht arbeiten.

Tobi

----------

## l3u

Wie wär's mit "find /verzeichnis/ | grep"? Dann schreib schön nacheinander die Dateinamen hin. Aber Man müßte ja an sich rausfinden können, wo diese Nummer herkommt, dann kann man sich das Suchen sparen!

----------

## Finswimmer

Nee. Immer noch der gleiche Fehler.

Es scheint so, dass jeder Befehl, der den Inhalt dieses Verzeichnisses ausgibt, erst in eine Variable geschriebn wird, und dann damit weitergearbeitet wird.

Auch wenn man ls * > /tmp/test macht, läuft die Variable über.

Ich weiß leider grade nicht, wie ich das umgehen kann...

Tobi

----------

## Anarcho

Das Problem ist, das das * von der bash aufgelöst wird und dann die Liste als Parameter angeben wird. 

Aber du kannst einem Programm nicht beliebig viele Paramter übergeben.

Daher muss du irgendwie anders, z.b. wie Libby schrieb, mit find die Liste erstellen.

Zeig dochmal welchen find Aufruf du verwendest hast.

----------

## Finswimmer

Hi,

ich verwende:

/usr/bin/find  $pfad > /tmp/makeprogress-tmp

Und so sieht es dann aus:

```
[16:32:53]|[root@tobi-rechner]|/home/tobi$ /tmp/makeprogress nvu

/tmp/makeprogress: line 15: /usr/bin/find: Argument list too long
```

Bin ich aber direkt in dem Verzeichnis, ohne Script nur per Konsole, und gebe find > 1 ein, geht es ohne Probleme.

Ursprünglich hatte ich das nicht mit der extra Datei, sondern direkt per /usr/bin/find $pfad | /bin/grep make.......

Ich bin grad ein bisschen ratlos...

Danke für deine Bemühungen.

Tobi

----------

## l3u

Komisch ... bei mir funktioniert folgendes einwandfrei:

```
erhome portage # pwd

/var/log/portage

erhome portage # find | wc -l

1019 (also 1019 Dateien, sprich: viele ;-)

erhome portage # find | grep "inkscape"

./3533-inkscape-0.43.log

./3644-inkscape-0.43.log

./3864-inkscape-0.43.log

./3532-inkscape-0.43.log

./3645-inkscape-0.43.log

./3863-inkscape-0.43.log
```

Die Fehlermeldung, die du bekommst, seht eher so aus, als ob dir Argumentliste für find zu lang wäre, nicht die für grep.

EDIT:

Wobei ich aber nach wie vor sicher bin, daß das der falsche Weg ist: in meinem Fall gabe es hier 6 verschiedene Inkscape-Log-Dateien zur Auswahl -- woher willst du so wissen, welche die aktuelle ist?Last edited by l3u on Fri Jan 13, 2006 3:50 pm; edited 2 times in total

----------

## Finswimmer

Ja, in der Konsole geht bei mir auch alles einwandfrei.

Aber da, wo das Script abbricht, bei der Datei handelt es sich um 38829   38838 1976075 (Ausgabe von wc)

Tobi

----------

## friedegott

Hm ich wuerd wohl die .c, .cc, .cpp und .o dateien zaehlen lassen und damit dann die Fortschritt abschaetzen...

```

#!/bin/sh

die() {

        echo $1

        exit 1

}

tail -n 1 /var/log/emerge.log | egrep -q "Compiling/Merging"

[ $? -eq 1 ] && die "no current merge found"

cm=$(tail -n 1 /var/log/emerge.log| awk '{ print $7 }' | awk -F: '{ print $1 }')

cm=${cm:1}

cm=`basename ${cm}`

echo $cm

nc=$(find /var/tmp/portage/$cm/ | egrep "\.c[cp]?p?$" | wc -l)

no=$(find /var/tmp/portage/$cm/ | egrep "\.o$" | wc -l)

echo "${no}/${nc}"

```

mal so auf die schnelle...

----------

## Anarcho

 *Finswimmer wrote:*   

> Hi,
> 
> ich verwende:
> 
> /usr/bin/find  $pfad > /tmp/makeprogress-tmp
> ...

 

Vielleicht steht in $path noch was mit * drin?

Sonst lass dir den Inhalt von $path mal anzeigen.

----------

## Finswimmer

Okay. Da waren echt noch ein paar Fehler drin.

```
#!/bin/bash

log="/var/log/portage/"`/usr/bin/ls /var/log/portage/ | /bin/grep -i $1`

Verarbeitet=`cat $log | /bin/grep "make\[.\]"|/bin/grep -i leaving |wc|gawk -F " " '{ print $1 }'`

#pfad="/var/tmp/portage/"`/usr/bin/ls /var/tmp/portage/|grep $1`"/work/"`/usr/bin/ls /var/tmp/portage/|grep $1`

paket=`/usr/bin/ls /var/tmp/portage/|grep $1`

pfad="/var/tmp/portage/"$paket"/work/"

/usr/bin/find  $pfad > /tmp/makeprogress-tmp

gesamt=` cat /tmp/makeprogress-tmp |/bin/grep -i makefile|grep -v ".am" |/bin/grep -v ".in"|wc|gawk -F " " '{ print $1 }'`

echo "Es wurden schon "$Verarbeitet" Verzeichnisse von" $gesamt "verarbeitet"
```

So ists besser.

Unter der Annahme, dass /var/tmp/portage immer schön sauber ist, gibt es keine Probleme.

Ich muss nur noch bei Gelegenheit eine Abfrage einfügen, dass, sofern mehrere LogDateien vorhanden sind, immer die aktuelle genommen wird.

Tobi

----------

## l3u

Naja, aber "immer schön sauber" heißt ja nicht zwingend, daß keine Logdateien für ältere Merges drin sind ... es muß doch rauszufinden sein, nach welchen Kriterien diese Zahl vorne am Log generiert wird!

----------

## Finswimmer

Nicht unbedingt.

Was für mein Script Voraussetzung ist, ist dass in /var/tmp/portage keine älteren (abgebrochenen) entpackte Source Pakete liegen.

Denn da sucht das Script nach dem Namen, den es dann übernimmt und in /var/log/portage/ danach sucht.

Da ich dann schon den richtigen Namen mit Versionsnummer habe, ist es nur noch wichtig, dass die neuste Version von der Log Datei genommen wird.

Könnte ja sein, dass man das Programm zweimal an einem Tag installieren muss...

Also fehlt nur noch diese Abfrage, und das Script geht dann für alle Programme die mittels make kompiliert werden...

Tobi

----------

## l3u

Das könnt man sich aber alles sparen, wenn man die Nummer vor der Logdatei wüßte ...

----------

## Finswimmer

```
#!/bin/bash

log="/var/log/portage/"`/usr/bin/ls -1 --sort=time /var/log/portage/ |/bin/grep -i $1 |/usr/bin/head -n 1`

Verarbeitet=`cat $log | /bin/grep "make\[.\]"|/bin/grep -i leaving |wc|gawk -F " " '{ print $1 }'`

#pfad="/var/tmp/portage/"`/usr/bin/ls /var/tmp/portage/|grep $1`"/work/"`/usr/bin/ls /var/tmp/portage/|grep $1`

paket=`/usr/bin/ls /var/tmp/portage/|grep $1`

pfad="/var/tmp/portage/"$paket"/work/"

let gesamt=`/usr/bin/find $pfad -type d | wc -l`-1

echo "Es wurden schon "$Verarbeitet" Verzeichnisse von" $gesamt "verarbeitet"
```

Neueste Variante:

Gesamt zählt alle Verzeichnisse, denn mir ist aufgefallen, dass make in alle Verzeichnisse reingeht, undabhänig davon, ob da eine Makefile drin ist.

log ist nun immer die aktuellste Datei von einem bestimmten Suchbegriff.

Nun müssten annährend richtige Ergebnisse entstehen.

Tobi

----------

