Rechnungstore
Anmeldungsdatum: 18. Februar 2011
Beiträge: 157
|
Hallo Zusammen, ich habe eine Datei (databases.txt), die eine Liste von Datenbanken enthält. Der SQL-Server läuft in einem Docker-Container (auf Basis von Debian 9). Jetzt möchte ich gerne einen SQL-Dump für jede Datenbank in der Liste erstellen. Folgender Befehl erstellt leider nur einen Dump von der ersten Datenbank in der Liste: | time while read db; do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT $db > $db.sql; done < databases.txt
|
wohingegen dieser Befehl (wie gewünscht) von allen in der Liste enthaltenen Datenbanken einen Dump erstellt: | time for db in $(cat databases.txt); do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT $db > $db.sql; done
|
Wo liegt im ersten Befehl mit der while-Schleife der Fehler?
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12527
|
Der Unterschied könnte daran liegen, dass die erste Variante immer ganze Zeilen nimmt, während die zweite nur Wörter nimmt. Zeig doch mal den Inhalt der DB-Datei.
|
Rechnungstore
(Themenstarter)
Anmeldungsdatum: 18. Februar 2011
Beiträge: 157
|
Moin rklm, aus Datenschutzgründen nicht im Original möglich, aber die Namen der Datenbanken sind nach folgendem Muster aufgebaut: d_string_nochnstring
Sie enthalten nur Buchstaben und Unterstriche, keine Leerzeichen oder ähnliches. In jeder Zeile steht ein Datenbankname. Wenn ich in der ersten Variante den ganzen Docker-Befehl durch echo ersetze, wird mir (wie erwartet) auch jeder einzelne Datenbankname in einer eigenen Zeile angezeigt.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12527
|
Rechnungstore schrieb:
aus Datenschutzgründen nicht im Original möglich, aber die Namen der Datenbanken sind nach folgendem Muster aufgebaut:
Bitte schick dann mal eine Datei, die so aussieht wie das Original - nur halt mit den echten Namen ersetzt. Es geht wirklich darum, das Format der einzelnen Einträge als auch das der Datei zu sehen.
Sie enthalten nur Buchstaben und Unterstriche, keine Leerzeichen oder ähnliches. In jeder Zeile steht ein Datenbankname. Wenn ich in der ersten Variante den ganzen Docker-Befehl durch echo ersetze, wird mir (wie erwartet) auch jeder einzelne Datenbankname in einer eigenen Zeile angezeigt.
Lass mal folgendes Kommando auf die Datei los. Damit kannst Du sehen, ob es da Leerzeichen am Zeilenende gibt:
|
Rechnungstore
(Themenstarter)
Anmeldungsdatum: 18. Februar 2011
Beiträge: 157
|
Es befand sich tatsächlich ein Leerzeichen in Zeile 9. Das Entfernen hat aber nichts geändert. Die Datei: database.txt Das Format der Datei | root@server:/backup/dbdump_temp# file databases.txt
databases.txt: ASCII text
|
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4212
|
Hm, also eigentlich sieht der erste Befehl soweit richtig aus. Was passiert denn, wenn Du einfach ein "echo $db" dort einsetzt statt dem docker-Befehl? Wurde die Liste unter Linux erstellt oder sind da vielleicht Windows-Zeilenumbrüche drin?
|
Rechnungstore
(Themenstarter)
Anmeldungsdatum: 18. Februar 2011
Beiträge: 157
|
Hallo Doc_Symbiosis, das mit echo habe ich probiert. Funktioniert wie erwartet. Die Liste wurde auf demselben Ubuntu 18.04 mit vim erstellt.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12527
|
Für die beiden Befehle mal in einer Shell aus, wo Du vorher set -x gesagt hast. Ansonsten fällt mir nur ein, die Variablen zu quoten: | time while read db; do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT "$db" > "$db.sql"; done < databases.txt
time for db in $(cat databases.txt); do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT "$db" > "$db.sql"; done
|
Vielleicht macht das ja den Fehler sichtbar.
|
Rechnungstore
(Themenstarter)
Anmeldungsdatum: 18. Februar 2011
Beiträge: 157
|
| root@server:/backup/dbdump_temp# time while read db; do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT "$db" > "$db.sql"; done < databases.txt
+ read db
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_string_jh
Warning: Using a password on the command line interface can be insecure.
+ read db
real 0m5.168s
user 0m0.213s
sys 0m0.502s
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 |
root@server:/backup/dbdump_temp# time for db in $(cat databases.txt); do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT "$db" > "$db.sql"; done
++ cat databases.txt
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
+ for db in $(cat databases.txt)
+ docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT c_dbname
Warning: Using a password on the command line interface can be insecure.
real 0m32.221s
user 0m1.252s
sys 0m2.200s
|
In dem zweiten Befehl steht in der Ausgabe natürlich jedes mal der echte Name der jeweiligen Datenbank aus der Liste und nicht "c_dbname".
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 7816
|
Probiere es einmal ohne time .
|
Rechnungstore
(Themenstarter)
Anmeldungsdatum: 18. Februar 2011
Beiträge: 157
|
Probiere es einmal ohne time.
Habe ich schon ganz am Anfang getestet. Kein Unterschied. Naja, egal letztlich bin ich ja mit der For-Schleife ans Ziel gekommen. Es ärgert mich immer nur ein wenig, wenn ich so grundlegende Dinge nicht verstehe.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12527
|
Rechnungstore schrieb:
Naja, egal letztlich bin ich ja mit der For-Schleife ans Ziel gekommen. Es ärgert mich immer nur ein wenig, wenn ich so grundlegende Dinge nicht verstehe.
Würde mir genau so gehen. Man sieht ja, dass der zweite read scheitert. Probier doch mal | while read db; s=$?; echo "Status $s"; ( exit $s ); do echo "read: <$db>"; done < databases.txt
|
Vielleicht ist das ja erhellend. Siehe help read wg. Rückgabewerten.
|
Ruth-Wies
Anmeldungsdatum: 12. April 2023
Beiträge: 7
|
OT Rechnungstore schrieb: … in einem Docker-Container (auf Basis von Debian 9). …
wiki.debian.org/LTS schrieb:
Debian LTS support for Debian 9 "Stretch" ended on June 30, 2022
Gibt es da nichts aktuelleres? Gleiches gilt für 18.04; das hat nur noch 49 Tage (bis Ende Mai).
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 611
|
Hmm... Ich hatte ein vergleichbares Problem mit HandBrakeCLI. Nach Abarbeiten der ersten Datei in der while loop wurden die loop beendet. Eine "while" Schleife ist leider nicht so stabil, wenn das in der loop aufgerufene Programm von stdin liest. Ich habe das Problem so umschifft, indem ich vor dem Aufruf des Programms ein 'echo "" | ' als pipe gesetzt habe. Dies wäre dann im Beispiel wie folgt zu implementieren:
time while read db; do echo "" | docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT $db > $db.sql; done < databases.txt
Ein Versuch wäre es aus meiner Sicht wert.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12527
|
shiro schrieb:
Eine "while" Schleife ist leider nicht so stabil, wenn das in der loop aufgerufene Programm von stdin liest.
Ah! Guter Punkt! Das wird es sein.
Ich habe das Problem so umschifft, indem ich vor dem Aufruf des Programms ein 'echo "" | ' als pipe gesetzt habe.
Es gibt noch zwei andere Varianten:
Stdin für diesen Prozess schließen read von einem anderen Dateideskriptor lesen lassen.
Kann es gerade nicht testen, aber so ungefähr: | # 1
time while read db; do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT $db > $db.sql <&-; done < databases.txt
# 2
exec 9<databases.txt
time while read db <&9; do docker exec -u 0 -i 5ae0a08b41d3 mysqldump -uUSER -pPASSWORT $db > $db.sql; done
|
Ggf. Variante 2 in eine Subshell packen, damit FD 9 automatisch wieder geschlossen wird. Ansonsten geht das auch mit exec 9<&- .
|