[solved] Mittels 'pv' den Fortschritt in Logdatei schreiben

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von pangu » 06.11.2013 16:36:09

Hi Cae,

könnte ich dein Skript genauso auch auf meiner Maschine verwenden, um die optimale BS zu ermitteln?
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von Cae » 06.11.2013 16:39:57

pangu hat geschrieben:Hi Cae,

könnte ich dein Skript genauso auch auf meiner Maschine verwenden, um die optimale BS zu ermitteln?
Ja, sogar genau so. Die Ausgabe unten wird durch das exit $? nie aufgerufen, so aenlich wie bei Perl das __END__.

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von pangu » 06.11.2013 17:30:02

Cae hat geschrieben:Also zumindest auf meiner Maschine ist das Lesen in Blockgroessen von 128 oder 256 MB optimal fuer's RAM:

Code: Alles auswählen

[...]
131072, 65536x	12.3 GB/s
262144, 32768x	12.3 GB/s
[...]
[/quote]

Megabyte?? Ich glaub wohl eher du meintest 128 Kilobyteblöcke, bzw. 256 Kb, oder nicht?? Bitte berichtige mich falls ich falsch liege, aber wenn man dem dd keine Einheit mitteilt, dann ist doch die Einheit 'bytes'.

bs=1 (Blockgröße 1 Byte)
bs=1K (Blockgröße 1Kilobyte)
bs=1M (Blockgröße 1Megabyte)

Oder änderst du da etwas mit deinem Awk-Befehl nach der Pipe ab?? Ich hab den awk-Befehl eh nicht verstanden, was da genau gemacht wird. Deswegen hatte ich ja vorhin nochmal sicherheitshalber nachgefragt, ob ich dein Skript so bei meiner Maschine verwenden kann. War mir etwas unsicher wegen dieser awk-Zeile :p

EDIT: Ich hab jetzt dein Skript an 4 verschiedenen Hosts durchlaufen lassen, und immer erhielt ich bei [b]16K Blockgröße[/b] den besten Throughput.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von Cae » 06.11.2013 20:14:49

Hups, da ist 'ne 2^10-Dimension verloren gegangen. Ja, es sind 128 bzw. 256 kB.

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von pangu » 06.11.2013 20:30:59

detix hat geschrieben:Sollte denn nicht einfach das reichen:

Code: Alles auswählen

(pv -f /dev/sda1 | dd of=/dev/null) >>/tmp/sicherung_aktiv.monitor 2>&1
also zum Testen sda1 nach /dev/null umgelenkt, der Inhalt der Temp-Datei sieht (gekürzt) so aus:

Code: Alles auswählen

55,1MB 0:00:01 [55,1MB/s] [>                                   ]  0% ETA 0:04:18
 102MB 0:00:02 [47,3MB/s] [>                                   ]  0% ETA 0:04:37
 147MB 0:00:03 [44,2MB/s] [>                                   ]  1% ETA 0:04:49
6,99GB 0:02:08 [56,7MB/s] [=================>                  ] 50% ETA 0:02:07
13,9GB 0:04:15 [58,2MB/s] [==================================> ] 99% ETA 0:00:00
  14GB 0:04:15 [55,9MB/s] [==================================>] 100%            
29286432+0 Datensätze ein
29286432+0 Datensätze aus
14994653184 Bytes (15 GB) kopiert, 255,875 s, 58,6 MB/s
Da ich das jetzt selbst austesten wollte, muss ich ja irgendwie angeben wie groß die zu kopierenden Datenmengen werden sollen. Das kann ich jedoch nur, wenn ich dd verwende und darin blocksize und count nutze. Will ja nicht warten, bis meine komplette /dev/sdx nach /dev/null kopiert wird. Also musste ich den Befehl wie folgt abändern, das Prinzip ist aber dasselbe wie bei dir, oder nicht? Ich hab ja den eigentlich Kopierprozess in Klammern gesetzt und damit in eine sub-shell:

Code: Alles auswählen

(dd if=/dev/zero bs=$bs count=$((4294967296 / $bs)) | pv -f -p -t -e -r -b -a -s 4G | dd of=/dev/null) >>output.monitor 2>&1
Damit generiere ich 4GB an Testdaten. Nun, ich habe folgendes festgestellt:

wenn ich 2>&1 ganz am Ende weglasse, dann wird zwar die output.monitor generiert, enthält aber immer 0 Bytes. Es landen keine Daten darin. Wenn ich 2>&1 verwende, dann funktioniert es (teilweise):

während der Prozess nämlich läuft und die Daten kopiert werden, dann steigt die Byte-Zahl der Datei "output.monitor" stetig an, und zwar bis zu 1701 Bytes. Währenddessen, wenn ich jedoch ein "cat output.monitor" versuche, kriege ich keine Ausgabe zurück, als ob die Datei leer wäre. Ich vermute mal, dass dort lediglich irgendwelche Art von Steuerzeichen drinlanden?

==> Erst wenn der Prozess komplett beendet ist, kann ich mir die output.monitor mit "cat output.monitor" anzeigen lassen und erhalte so eine Ausgabe:
# cat output.monitor
33554432+0 Datensätze ein [ 191MB/s] [=======================> ] 97% ETA 0:00:00
33554432+0 Datensätze aus
4GB 0:00:21 [ 191MB/s] [ 191MB/s] [=======================>] 100%
4294967296 Bytes (4,3 GB) kopiert, 21,4506 s, 200 MB/s
6816936+2117326 Datensätze ein
8388608+0 Datensätze aus
4294967296 Bytes (4,3 GB) kopiert, 21,4513 s, 200 MB/s
die output.monitor hat genau 2005 Bytes. Also irgendwie immer noch nicht das, was ich eignetlich erreichen wollte. Ich möchte in die output.monitor reinschauen können, um dne aktuellen Stand anzeigen lassen zu können. Momentan krieg ich das so aber wohl nicht gebacken. :cry:
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von pangu » 07.11.2013 10:08:42

Habe die Lösung!

Und zwar brauch ich den grafischen Schnickschnack mit der Fortschrittsanzeige als Balkenform gar nicht. Das generiert ja nur diese Steuercodes und anhand des Bufferings krieg ich diese Anzeigeprobleme. Habe nun einfach den Schalter -n verwendet für "numeric" Anzeige. Dann braucht man den Schalter -f nicht mehr.

Der Einzeiler sieht dann also so aus (für meinen Test):

Code: Alles auswählen

(dd if=/dev/zero bs=$bs count=$((4294967296 / $bs)) | pv -n -p -t -e -r -a -s 4G | dd of=/dev/null) >test.monitor 2>&1
und in der test.monitor wird folgender Output generiert. Die einzelnen Zeile entsprechen dem Prozentanteil, wieviel bereits abgeschlossen ist. Und wenn das bei 100 angelangt ist, kriegt man am Ende auch die Zusammenfassung mit Infos wie "übertragene Datenmenge", durchschnittlicher Durchsatz, usw...
4
9
13
18
23
27
32
37
41
46
50
55
60
64
69
74
78
83
88
92
97
33554432+0 Datensätze ein
33554432+0 Datensätze aus
4294967296 Bytes (4,3 GB) kopiert, 21,5802 s, 199 MB/s
6963036+1923266 Datensätze ein
8388608+0 Datensätze aus
4294967296 Bytes (4,3 GB) kopiert, 21,5811 s, 199 MB/s
Somit genau das was ich haben wollte. Ich kann jederzeit durch Betrachten der "test.monitor" nachschauen, wieweit der dd-Prozess ist.

EDIT: Das einzige was noch blöd ist, daß ca. 2x in der Sekunde eine neue Zeile geschrieben wird. Das bedeutet, daß im Outputfile so was drinstehen wird beim Klonen einer 2TB Platte:
0
0
0
0
0
0
0
0
0
...und nach Stunden immer noch hunderte/tausende Zeilen mit diesen Nullen
5
5
5
5
5
5
5
5
5
5
5
5
...und so weiter...
Wie könnte man das unterbinden, so daß KEINE neue Zeile verwendet wird ? Ich glaub mittels dem pv-Kommando kann man das ja nirgends einstellen, denn in der 'man' heißt es ja, dass immer eine neue Zeile geschrieben wird.
-n: Numeric output. Instead of giving a visual indication of progress, pv will give an integer percentage, one per line, on standard error, ...
könnte man da evtl. noch nachträglich awk pipen und das so irgendwie lösen?? Evtl. mit nem if- und last statement innerhalb awk?? Meillo, wo steckst du awk-Guru? :) *help*
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
ThorstenS
Beiträge: 2875
Registriert: 24.04.2004 15:33:31

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von ThorstenS » 07.11.2013 14:24:06

Schreib den output nach /dev/shm/monitor.unsorted und lass
periodisch ein uniq /dev/shm/monitor.unsorted > /dev/shm/monitor.sorted laufen, in diese Datei schaust du dann rein.
Achja, falls du Start und Endzeit mitloggen willst, ich mach das immer so:

Code: Alles auswählen

#!/bin/bash                                                                                                                                 
# Laufzeit eines Scripts ausgeben by ThorstenS
echo -e "Start:\v\t$(date "+%Y-%m-%d %H:%M")"
time_start=$(date +%s)

sleep 3

time_end=$(date +%s)
time_elapsed=$((time_end - time_start))
echo -e "Ende:\v\t$(date "+%Y-%m-%d %H:%M")"
echo -e "Dauer:\v\t$(( time_elapsed / 3600 ))h $(( time_elapsed %3600 / 60 ))m $(( time_elapsed % 60 ))s"
EDIT:
sed kann dir die Datei auch periodisch zurechtstutzen, laut http://www.catonmat.net/blog/sed-one-li ... art-three/ machst du dann einfach ein sed -i '$!N; /^\(.*\)\n\1$/!P; D' /dev/shm/monitor.unsorted

Benutzeravatar
detix
Beiträge: 1699
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von detix » 07.11.2013 17:12:45

pangu hat geschrieben:Das einzige was noch blöd ist, daß ca. 2x in der Sekunde eine neue Zeile geschrieben wird.
Eigentlich wird nur jede Sekunde eine Zeile geschrieben,
du kannst pv mit dem Parameter "-i" anweisen zB nur jede Minute zu schreiben (-i 60),
wirst ja nicht im Sekundentakt in die Datei schauen,
die Anzahl der Zeilen entspräche dann sogar der Dauer in Minuten, zum Testen:

Code: Alles auswählen

(pv -n -i 60 /dev/sda | dd of=/tmp/sicherung) >>/tmp/sicherung_aktiv.monitor 2>&1
0
1
1
2
9241344+0 Datensätze ein
9241344+0 Datensätze aus
4731568128 Bytes (4,7 GB) kopiert, 241,658 s, 19,6 MB/s
Abbruch (bloß nicht durchlaufen lassen!) in der 4ten Zeile (=4 Minuten), passt auch ohne Rechnerei.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von pangu » 07.11.2013 18:26:17

Danke für diese Info, würde aber trotzdem gerne wissen/lernen, wie man das Logfile so frisieren könnte, dass immer nur der letzte output (=Zahl) zu sehen ist.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von pangu » 07.11.2013 18:47:06

ThorstenS hat geschrieben:Schreib den output nach /dev/shm/monitor.unsorted und lass
periodisch ein uniq /dev/shm/monitor.unsorted > /dev/shm/monitor.sorted laufen, in diese Datei schaust du dann rein.
was genau macht /dev/shm , warum dort hinein schreiben die Logdatei? shm ist irgendwie shared-memory, soweit so gut, aber ich verstehe nicht den Sinn. Vielleicht kannst du mich aufklären?
ThorstenS hat geschrieben:sed kann dir die Datei auch periodisch zurechtstutzen, laut http://www.catonmat.net/blog/sed-one-li ... art-three/ machst du dann einfach ein
sed -i '$!N; /^\(.*\)\n\1$/!P; D' /dev/shm/monitor.unsorted
Ich würde jetzt schon wirklich gerne wissen, wie ich in diesen Befehl erweitern könnte ...

Code: Alles auswählen

(dd if=/dev/zero bs=16384 count=131072 | pv -n -p -t -e -r -a -s 2G | dd of=/dev/null) 2>active_dd.monitor 
dass weiterhin active_dd.monitor verwendet wird als Logdatei, und diese eben gleich beim Beschreiben angepasst wird. Ist das denn mit awk nicht irgendwie möglich? Ich bin mir (fast) sicher, daß es mit awk klappen sollte.

evtl. kann ich auch einfachhalber einfach irgendwie sed's Einzeiler

Code: Alles auswählen

sed '$d' dateiname
nutzen? Das entfernt die letzte Zeile. Wie müsste ich das aber in den oben genannten Befehl einfügen, damit es jedesmal ausgeführt wird, wenn der pv-Befehl etwas ins logfile schreibt? Das hier würde ja nicht funktionieren...

Code: Alles auswählen

(dd if=/dev/zero bs=16384 count=131072 | pv -n -p -t -e -r -a -s 2G | dd of=/dev/null) 2>active_dd.monitor && sed '$d' active_dd.monitor
weil sed nur 1x ausgeführt werden würde.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Benutzeravatar
ThorstenS
Beiträge: 2875
Registriert: 24.04.2004 15:33:31

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von ThorstenS » 07.11.2013 20:56:12

Alles unter /dev/shm/ bleibt im RAM und wird nicht auf Platte geschrieben.
Die Platten performance willst du dir doch nicht durch das unnötige Schreiben eines Logfiles ausbremsen, oder?

Starte kurz vor deinem dd/pv Befehl mit start-stop-daemo ein zwotes Script.
Gib ein pidfile an, so wie z.B. in /etc/init.d/ssh es gemacht wird.
Im zwoten Script kannst du mit einem while true nach einer Wartezeit von ca. 10 Sekunden das Logfile einkürzen, so wie ich es oben schrieb.
Wenn der dd/pv Befehl in der subshell vom 1. Script fertig ist, schießt du ihn elegant mit start-stop-daemo wieder ab. Mehr Mühe würde ich nicht darauf verwenden.

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von pangu » 07.11.2013 22:20:00

ThorstenS hat geschrieben:und lass periodisch ein "uniq /dev/shm/monitor.unsorted > /dev/shm/monitor.sorted" laufen.
wozu? damit würde ich die doppelte Zeilen entfernen, aber das ist ja immer noch nicht das, was ich ursprünglich haben wollte. Bitte versteh mich nicht falsch, ich bin für jeden Tip dankbar. Mir gehts aber nicht immer nur darum, das Ziel zu erreichen, sondern ich möchte dabei immer auch was lernen WIE man es macht und welche Möglichkeiten es gibt und welche am elegantesten/saubersten sind. Um zurück zum Thema zu kommen: mit uniq würde ich doppelte Zeilen vermeiden, dadurch krieg ich aber trotzdem im output file Ausgaben wie:
1
2
3
4
5
6
[...usw]
das wären halt maximal 100 Zeilen, aber das sind eben 99 Zeilen zu viel und überflüssig IMHO. Ich find das nicht sauber genug. Nehmen wir mal theoretisch an, es gäbe einen Praxisfall indem hier counterwise von 1-9999999999999 Zahlen hochgezählt würden. Das wäre eine Datenflut und nicht vertretbar. Daher: ich möchte definitiv immer nur die letzte Zeilenausgabe angezeigt, bzw. geloggt bekommen haben.
ThorstenS hat geschrieben:Achja, falls du Start und Endzeit mitloggen willst...
danke für die Einsicht in dein Skript, aber da nutze ich lieber ganz komfortabel den Befehl 'time'
ThorstenS hat geschrieben:sed kann dir die Datei auch periodisch zurechtstutzen, laut http://www.catonmat.net/blog/sed-one-li ... art-three/ machst du dann einfach ein "sed -i '$!N; /^\(.*\)\n\1$/!P; D' /dev/shm/monitor.unsorted"
Hab diesen Befehl einfach über eine monitor.unsorted drübergejagt, aber die blieb unverändert ??
Zuletzt geändert von Meillo am 21.11.2013 09:37:23, insgesamt 1-mal geändert.
Grund: BB-Tags repariert
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von Cae » 08.11.2013 02:08:17

Man koennte das in

Code: Alles auswählen

| while read -r line; do printf '%s\n' "$line" >"$statusfile"; done
reinpipen, das wuerde immer genau eine Zeile lesen und alles in $statusfile damit ueberschreiben.

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von pangu » 08.11.2013 11:33:27

klappt irgendwie auch nicht Cae, ich vermute einfach deswegen, weil ja pv das irgendwie buffered und dann erst ausgibt. Das ist ja keine Schleife die dort abläuft, oder nicht? oder hab ich das einfach nur falsch interpretiert und den Befehl falsch konstruiert? Ich habs so versucht gehabt:

Code: Alles auswählen

(dd if=/dev/zero bs=16384 count=131072 | pv -n -p -t -e -r -a -s 2G | dd of=/dev/null) | while read -r line; do printf '%s\n' "$line" 2>test.monitor; done
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: [solved] Mittels 'pv' den Fortschritt in Logdatei schrei

Beitrag von Cae » 09.11.2013 01:06:40

Die Umleitung von stderr ist an der verkehrten Stelle, printf schreibt ja schon nach stdout. So sollte es tun:

Code: Alles auswählen

( dd ... | pv ... ) 2>&1 | while read ... printf ... >test.monitor; done
Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
Meillo
Moderator
Beiträge: 8781
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Mittels 'pv' den Fortschritt in Logdatei schreiben

Beitrag von Meillo » 21.11.2013 09:46:22

(Ich habe den Thread nur ueberflogen, nicht aber im Detail gelesen. Mir scheint, dass vieles schon gesagt worden ist, aber die Klarheit beim uniq-Hinweis hat mir noch gefehlt.)
pangu hat geschrieben: Der Einzeiler sieht dann also so aus (für meinen Test):

Code: Alles auswählen

(dd if=/dev/zero bs=$bs count=$((4294967296 / $bs)) | pv -n -p -t -e -r -a -s 4G | dd of=/dev/null) >test.monitor 2>&1
EDIT: Das einzige was noch blöd ist, daß ca. 2x in der Sekunde eine neue Zeile geschrieben wird. Das bedeutet, daß im Outputfile so was drinstehen wird beim Klonen einer 2TB Platte:
0
0
0
0
0
0
0
0
0
...und nach Stunden immer noch hunderte/tausende Zeilen mit diesen Nullen
5
5
5
5
5
5
5
5
5
5
5
5
...und so weiter...
Wie könnte man das unterbinden, so daß KEINE neue Zeile verwendet wird ?
Du willst verhindern, dass doppelte, identische Zeilen erscheinen? Dann pipe durch uniq(1). Das unterdrueckt Zeilen, die identisch mit der vorherigen Zeile sind.

Code: Alles auswählen

(dd if=/dev/zero bs=$bs count=$((4294967296 / $bs)) | pv -n -p -t -e -r -a -s 4G | dd of=/dev/null) 2>&1 | uniq >test.monitor
Use ed once in a while!

Antworten