Udalrich
Anmeldungsdatum: 15. Mai 2019
Beiträge: 525
|
Ein per Skript gestartetes Kommando „links von der Pipe“ verbinde ich mit dem zenity-Werkzeug „rechts von der Pipe“, damit Zenity per GUI einen zeitlosen pulsierenden Statusbalken anzeigt, solange das Kommmando läuft:
gio copy Test.mp4 smb://Fritz/pfad/ | zenity --progress --text=Kopiere… --pulsate --auto-close Wie andere Kommandos auch, kann gio copy über seinen Parameter --progress einen fortschreitenden Statustext in einer und derselben Zeile ausgeben, bis die Datei fertig übertragen ist:
X,0 MB von 20,0 MB übertragen (1 MB/s)
Könnte man diese fortschreitende Statuszeile mit einer weiteren Pipe „abfangen“, mit einem # vornedran versehen und dann an zenity geben? Denn zenity --progress horcht auf „links von der Pipe“ kommende Zeilen, wenn sie nur eine Zahl enthalten und nimmt dies als GUI-Prozentbalken, und wenn die Zeile mit # beginnt, nimmt Zenity sie für die GUI-Textzeile. Beispiel:
for i in {0..100..25}; do echo $i; echo "#Proz_$i"; sleep 1; done | zenity --progress --auto-close Oder für Kommandos, wo keine Prozentzahl verfügbar ist, daher nur ein pulsierender Prozentbalken, aber ein sich ändernder Text:
for i in {0..100..25}; do echo "#Text_$i"; sleep 1; done | zenity --progress --pulsate --auto-close
|
karzer
Wikiteam
Anmeldungsdatum: 10. April 2022
Beiträge: 1288
Wohnort: Bad Oeynhausen
|
Hallo, dazu müsste man auf die Programm-Ausgabe während der Laufzeit zugreifen können. Ich wüsste allerdings nicht, dass das geht. Der awk-Teil hier etwa gio copy --progress Test.mp4 smb://Fritz/pfad/ | awk '{print $2}' würde erst nach dem Ende des copy-Befehls ausgeführt werden und letztendlich nicht den derzeitigen Status, sondern den letzten Übertragungs-Stand ausgeben (also die Größe der Datei).
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 917
|
Könnte man diese fortschreitende Statuszeile mit einer weiteren Pipe „abfangen“, mit einem # vornedran versehen und dann an zenity geben?
Die Ausgabe von "gio copy --progress" kannst du dir mit xxd dumpen. Es ist ein "^M ESC \[ K" vor jeder Zeile. Aus diesem Grund kannst du diese Ausgabe mit sed verändern, bevor du die Strings an zenity weiter gibst. z.B.
gio copy --progress Test.mp4 smb://Fritz/pfad/ | sed 's/\r.\[K/\n#/g' | zenity --progress --text=Kopiere… --pulsate --auto-close
|
karzer
Wikiteam
Anmeldungsdatum: 10. April 2022
Beiträge: 1288
Wohnort: Bad Oeynhausen
|
Hallo shiro, bei mir sieht die xxd-Ausgabe am Anfang so aus: ..[KTransferred Stellen die beiden Punkte wirklich ^M und ESC dar?
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 917
|
karzer schrieb: ..[KTransferred
Stellen die beiden Punkte wirklich ^M und ESC dar?
Hmm, es ist ein paar Jahre her, dass ich mit dem DEC VT100 programmiert hatte. Soweit ich mich erinnern kann, bewirkt ein "ESC [ K" das Löschen der Zeile, in der sich der Cursor befindet. Das ^M davor positioniert den Cursor wieder an den Zeilenanfang.
|
karzer
Wikiteam
Anmeldungsdatum: 10. April 2022
Beiträge: 1288
Wohnort: Bad Oeynhausen
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12801
|
Udalrich schrieb: Ein per Skript gestartetes Kommando „links von der Pipe“ verbinde ich mit dem zenity-Werkzeug „rechts von der Pipe“, damit Zenity per GUI einen zeitlosen pulsierenden Statusbalken anzeigt, solange das Kommmando läuft:
gio copy Test.mp4 smb://Fritz/pfad/ | zenity --progress --text=Kopiere… --pulsate --auto-close Wie andere Kommandos auch, kann gio copy über seinen Parameter --progress einen fortschreitenden Statustext in einer und derselben Zeile ausgeben, bis die Datei fertig übertragen ist:
X,0 MB von 20,0 MB übertragen (1 MB/s)
Könnte man diese fortschreitende Statuszeile mit einer weiteren Pipe „abfangen“, mit einem # vornedran versehen und dann an zenity geben?
Was meinst Du mit "einer weiteren Pipe"? Der Prozess hat ja nur ein Stdout, also kannst Du da auch nur eine Pipe bilden. Was Du brauchst, wenn ich das richtig sehe, ist etwas im Datenstrom, das die Ausgaben von gio copy so formatiert, dass es entweder eine Zahl oder eine Zeile mit "#" am Anfang ist. So etwas macht man typischerweise mit sed . In Deinem Fall ist auch noch wichtig, dass man die Option "--unbuffered" verwendet, weil sonst der zeitliche Ablauf durch die Pufferung in sed verfälscht wird. Ich habe gio nicht dazu bekommen können, mehrere Statuszeilen auszugeben. Wenn das, was ich gesehen habe, das richtige Muster ist, dann würde sed nicht reichen, weil man noch den Prozentwert berechnen muss. Dann müsste man das ggf. mit awk machen. Transferred 0 bytes out of 0 bytes (0 bytes/s) Man könnte das so machen: | gio copy --progress ... | awk '{
if (match($0, /Transferred ([0-9]+) bytes out of ([0-9]+) bytes \([0-9]+ bytes\/s\)/, g)) { printf "%d\n#%d bytes written\n", g[2]==0 ? 0 : 100*g[1]/g[2], g[1] }
}'
|
|
Udalrich
(Themenstarter)
Anmeldungsdatum: 15. Mai 2019
Beiträge: 525
|
Faszinierend! Danke Euch für die Einblicke in Verkettung von Kommandozeilenprogrammen. Verständnisfrage bitte: Warum bekommt mein schönes Gawk und andere Programme nur am Ende des Kopierens die letze Zeile vom Pipe-Lieferanten, während Hexdump alle Zeilen kriegt auch während des Kopierens? Und noch ein Problem: Mit dem sed -Einzeilerskript klappt das bei mir noch nicht ganz richtig: es schweigt, bis die Datei ganz übertragen wurde und gibt dann alle zuvor vom gio getätigten Zeilen auf einmal untereinander aus, während Gawk wirklich nur die allerletzte Zeile ausgibt. Also (Größen geändert zum leichteren Lesen) : gio copy --progress vid.mp4 smb://Fritz/pfad/ | sed 's/\r.\[K/\n#/g'
…wartet auf Kopierende, dann auf einmal…
#1 MB von 15 MB übertragen (10 MB/s)
#10 MB von 15 MB übertragen (10 MB/s)
#15 MB von 15 MB übertragen (10 MB/s)
gio copy --progress vid.mp4 smb://Fritz/pfad/ | gawk '{print}'
…wartet auf Kopierende, dann…
#15 MB von 15 MB übertragen (10 MB/s)
Das Hexdump-Kommando xxd und auch hexdump hingegen kriegen jede Zeile während des Kopierens:
gio copy --progress vid.mp4 smb://Fritz/pfad/ | hexdump -C
00000000 0d 1b 5b 4b 32 36 32 2c 31 c2 a0 6b 42 20 76 6f |..[K262,1..kB vo|
00000010 6e 20 31 35 2c 31 c2 a0 4d 42 20 c3 bc 62 65 72 |n 15,1..MB ..ber|
00000020 74 72 61 67 65 6e 20 28 32 36 32 2c 31 c2 a0 6b |tragen (262,1..k|
00000030 42 2f 73 29 0d 1b 5b 4b 31 2c 30 c2 a0 4d 42 20 |B/s)..[K1,0..MB |
00000040 76 6f 6e 20 31 35 2c 31 c2 a0 4d 42 20 c3 bc 62 |von 15,1..MB ..b|
00000050 65 72 74 72 61 67 65 6e 20 28 31 2c 30 c2 a0 4d |ertragen (1,0..M|
00000060 42 2f 73 29 0d 1b 5b 4b 31 2c 38 c2 a0 4d 42 20 |B/s)..[K1,8..MB |
[…]
|
Udalrich
(Themenstarter)
Anmeldungsdatum: 15. Mai 2019
Beiträge: 525
|
Danke auch an Rklm! (Wir schrieben unsere Antworten fast zeitgleich) Die Textangabe (#10 MB von 15 MB übertragen) würde bei Zenity genügen, statt Prozent. Hauptsache man sieht, wo man steht. Auf einen Parameter wie --unbuffered hatte ich gehoft, aber er bringt leider noch keinen Erfolg?
gio copy --progress vid.mp4 smb://Fritz/pfad/ | sed --unbuffered 's/\r.\[K/\n#/g'
…wartet auf Kopierende, dann auf einmal…
#1 MB von 15 MB übertragen (10 MB/s)
#10 MB von 15 MB übertragen (10 MB/s)
#15 MB von 15 MB übertragen (10 MB/s)
}
|
karzer
Wikiteam
Anmeldungsdatum: 10. April 2022
Beiträge: 1288
Wohnort: Bad Oeynhausen
|
Hallo, Udalrich schrieb:
Und noch ein Problem: Mit dem sed -Einzeilerskript klappt das bei mir noch nicht ganz richtig: es schweigt, bis die Datei ganz übertragen wurde und gibt dann alle zuvor vom gio getätigten Zeilen auf einmal untereinander aus, während Gawk wirklich nur die allerletzte Zeile ausgibt.
wird denn die Ausgabe korrekt mit Hashtag an zenity übergeben?
|
Udalrich
(Themenstarter)
Anmeldungsdatum: 15. Mai 2019
Beiträge: 525
|
karzer schrieb: Hallo, Udalrich schrieb:
Und noch ein Problem: Mit dem sed -Einzeilerskript klappt das bei mir noch nicht ganz richtig: es schweigt, bis die Datei ganz übertragen wurde und gibt dann alle zuvor vom gio getätigten Zeilen auf einmal untereinander aus, während Gawk wirklich nur die allerletzte Zeile ausgibt.
wird denn die Ausgabe korrekt mit Hashtag an zenity übergeben?
Vermutlich, siehe bitte meine Ausgabe-Codeblöcke von 14:49h, wo der Sed-Einzeiler durchaus die # vorne dransetzt. Aber das Problem liegt vor Zenity, also an Sed, denn als letzter Prozeß nach Gio schreibt es während der Gio-Dateiübertragung nichts, sondern erst am Ende des Kopierens alle Gio-Ausgaben auf einmal untereinander. Daher kann Zenity gar nicht wie gewünscht funktionieren. Warum Sed alle Gio-Zeilen auf einmal ausgibt, während Awk nur die letzte Zeile kriegt, ist mir unklar trotz Shiros Hinweis auf die ESC-Zeichen (also ASCII kleiner 32). Diese Pipe-/Prozeß-IO-Feinheiten sind mir etwas rätselhaft. Hexdump hingegen bekommt als Prozeß direkt nach Gio durchaus alles Ausgaben von Gio und zeigt sie auch an.
|
karzer
Wikiteam
Anmeldungsdatum: 10. April 2022
Beiträge: 1288
Wohnort: Bad Oeynhausen
|
Hallo, Udalrich schrieb: Warum Sed alle Gio-Zeilen auf einmal ausgibt, während Awk nur die letzte Zeile kriegt, ist mir unklar trotz Shiros Hinweis auf die ESC-Zeichen (also ASCII kleiner 32).
Das hängt einfach mit den Eigenheiten von Pipes zusammen. Die funktionieren so, das der Standard-Output von einem Befehl erst nach dessen Ausführung an den Nächsten
weitergegeben wird. Also kann sed nicht während der Ausführung von gio copy etwas ausgeben. Deswegen war ich mir auch nicht sicher, ob das mit zenity funktioniert. Das solltest du vielleicht nochmal testen.
Hexdump hingegen bekommt als Prozeß direkt nach Gio durchaus alles Ausgaben von Gio und zeigt sie auch an.
Wie das mit hexdump (bzw. xxd) ist, weiß ich nicht. EDIT:
Auf einen Parameter wie --unbuffered hatte ich gehoft, aber er bringt leider noch keinen Erfolg?
gio copy --progress vid.mp4 smb://Fritz/pfad/ | sed --unbuffered 's/\r.\[K/\n#/g'
…wartet auf Kopierende, dann auf einmal…
#1 MB von 15 MB übertragen (10 MB/s)
#10 MB von 15 MB übertragen (10 MB/s)
#15 MB von 15 MB übertragen (10 MB/s)
Das könnte man noch versuchen: gio copy --progress vid.mp4 smb://Fritz/pfad/ | stdbuf -o0 sed 's/\r.\[K/\n#/g' Das schaltet das Puffern auch aus.
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 917
|
Oh je, das Buffering schlägt zu. Da die Ausgabe nicht Zeilenweise sondern im Stream erfolgt, hast du das Problem. Ich habe jetzt mal einen brutal einfachen Vorschlag, der sicher noch optimiert werden kann: gio copy --progress vid.mp4 smb://Fritz/pfad/ | while read -d $'\x1b' i; do echo "#${i:2}"; done | zenity --progress --text=Kopiere… --pulsate --auto-close Hierbei wird der Stream mit einem <ESC> (\x1b) als Trennzeichen gelesen. Die eingelesene Zeile wird mit einem "#" am Anfang ab der Spaltenposition 2 ausgegeben. Damit wird das [K nicht mit an zenity ausgegeben.
|
TNTMaster
Anmeldungsdatum: 30. Juli 2009
Beiträge: 851
|
Das Problem ist, daß gio nicht zeilenweise ausgibt, sondern immer in die gleiche Zeile schreibt, das kann man mit read auffangen und die 3 Zeichen am Anfang abschneiden:
| gio copy --progress vid.mp4 smb://Fritz/pfad/ \
| while read -d $'\r' a; do echo "#${a:3: -1}"; done | zenity --progress --pulsate --auto-close
|
Gruß TNT
|
karzer
Wikiteam
Anmeldungsdatum: 10. April 2022
Beiträge: 1288
Wohnort: Bad Oeynhausen
|
shiro schrieb: Oh je, das Buffering schlägt zu. Da die Ausgabe nicht Zeilenweise sondern im Stream erfolgt, hast du das Problem. Ich habe jetzt mal einen brutal einfachen Vorschlag, der sicher noch optimiert werden kann: gio copy --progress vid.mp4 smb://Fritz/pfad/ | while read -d $'\x1b' i; do echo "#${i:2}"; done | zenity --progress --text=Kopiere… --pulsate --auto-close Hierbei wird der Stream mit einem <ESC> (\x1b) als Trennzeichen gelesen. Die eingelesene Zeile wird mit einem "#" am Anfang ab der Spaltenposition 2 ausgegeben. Damit wird das [K nicht mit an zenity ausgegeben.
Shiros Vorschlag ist gut. Ich würde das noch folgendermaßen verändern: gio copy --progress mnt/gdrive/chromeos-linux-2022-06-22.tini . | while read -d $'\x1b' i; do echo "#${i:14}"; done
Hierbei startet echo beim 14. Zeichen, also mit der derzeitigen Übertragung: #1.0 MB out of 1.6 GB (1.0 MB/s)
#367.0 MB out of 1.6 GB (367.0 MB/s)
#716.2 MB out of 1.6 GB (716.2 MB/s)
#781.2 MB out of 1.6 GB (781.2 MB/s)
...
|