[gelöst] Shell-Skript - Frage zur Ausgabe

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Fjunchclick

[gelöst] Shell-Skript - Frage zur Ausgabe

Beitrag von Fjunchclick » 15.07.2012 16:26:39

Moin,
ich möchte mir mal ein kleines Skript basteln, mit dem ich mein Backup über BackInTime, verschiedene andere Dinge und ein Image mit fsarchiver sichern möchte. Dazu mal eine Frage:
Mein Kommando für das Sichern des Images sieht so aus:

Code: Alles auswählen

fsarchiver savefs -o -j2 -A -a -v -z3 /media/SamsungStory/farnsworth_image.fsa /dev/sda1
Das funktioniert auch. Der Schalter -v bewirkt ja, dass fsarchiver ausgibt, was gerade gemacht wird. Und zwar eine Zeile nach der anderen, d.h. der Text scrollt eben ganz normal durch.
Ich möchte das aber gerne so haben, dass jede Meldung immer wieder gelöscht und die nächste in die gleiche Zeile geschrieben wird. Dass es also, wenn das Skript läuft nur eine Zeile gibt, in der die fsarchiver-Meldungen nacheinander erscheinen, ohne dass etwas scrollt. Soll einfach der Übersicht dienen. Ich hoffe, ihr versteht, wie ich das meine.

Wie mache ich das?
Zuletzt geändert von Fjunchclick am 16.07.2012 11:53:34, insgesamt 1-mal geändert.

Liffi
Beiträge: 2345
Registriert: 02.10.2004 01:33:05

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von Liffi » 15.07.2012 17:08:16

Vielleicht in eine Datei ausgeben lassen und diese dann per watch und tail ausgeben lassen. watch kann zwar nur 0.1s Intervalle.

Nachteil: watch ist fullscreen.

EDIT:: Als Ersatz von watch kannst du auch das folgende benutzen. Ich hab es mal geschrieben, als watch bei mir nicht gut mit UTF8 funktionieren wollte.
Wenn das Skript mywatch heißt wäre die Aufrufsyntax: "mywatch 0.1s tail -1 ausgabe_file" um jede Zehntelsekunde die letzte Zeile der Datei auszugeben.
Hab nicht ausprobiert, ob es auch mit anderen Shells funktioniert. "$($*)" ist möglicherweise nicht sehr portabel.

Code: Alles auswählen

#!/bin/zsh

INTERVALL="$1"
blubb2=""
shift
blubb=$($*)

while true
do
    if [ "$blubb2" != "$blubb" ];
    then
        clear && print $blubb
        blubb2=$blubb
    fi
    sleep $INTERVALL
    blubb=$($*)

done

WPSchulz
Beiträge: 264
Registriert: 19.12.2010 17:13:53
Wohnort: Germany/ Dietzenbach
Kontaktdaten:

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von WPSchulz » 15.07.2012 18:24:43

Das läßt sich mit printf, Begrenzung der Länge des anzuzeigenden Strings und "Carriage return" lösen

Code: Alles auswählen

printf "%-71s\r" "  $i"
Beispielsweise verwende ich dies mehrfach in meinem Script kn-what
http://www.wp-schulz.de/knoppix/kn-script.html#kn-what
Gruss Werner * Eigene Rescue-CD
Grml remaster
Knoppix remaster

Fjunchclick

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von Fjunchclick » 16.07.2012 10:38:52

Puh, ich habe jetzt mal eine Menge rumprobiert aber ich komme nicht weiter. Leider habe ich nämlich überhaupt keine Ahnung von Shell-Skripting. Das hier ist, von ein paar Dreizeilern mal abgesehen, das erste Mal, dass ich mich damit befasse.

Ich verstehe nicht, wie ich jetzt den fsarchiver-Befehl mit euren vorgeschlagenen Lösungen zusammen bringe. Die Ausgaben von fsarchiver in eine Datei schreiben (wie mache ich das?) und dann in festen Zeitintervallen wieder auslesen ist nicht optimal, weil ja die Ausgaben von fsarchiver nicht regelmäßig sind.

Bei der Lösung von WPSchulz weiß ich leider auch nicht so recht, wie ich das für mein Anliegen umsetzen muss.

Wäre nett, wenn ihr vielleicht noch etwas ausführlicher sein könntet.

Es geht mir übrigens gar nicht darum, was genau fsarchiver da ausgibt, also welche Datei gerade gesichert wird, sondern eigentlich nur um die Fortschrittsanzeige. Es ist halt blöd, wenn fünf Minuten gar nichts passiert, bis die Sicherung fertig ist. Und bei der Ausgabe gibt es eben am Anfang jeder Zeile eine Prozentangabe.

Wenn es also irgendeine andere Möglichkeit der Fortschrittsanzeige geben sollte (wie z.B. pv mit dd), wäre ich natürlich auch damit zufrieden.
Es muss auch gar keine absolute Angabe sein, mir reicht es schon, wenn man einfach nur sieht, dass der Rechner etwas tut und sich nicht etwa schon längst aufgehängt hat.

lhfloss
Beiträge: 261
Registriert: 07.10.2007 21:02:15
Lizenz eigener Beiträge: MIT Lizenz

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von lhfloss » 16.07.2012 10:59:56

Ich hab gestern mal ein bisschen in C herumprobiert und das kam dabei raus:
NoPaste-Eintrag36563
Kompilieren mit

Code: Alles auswählen

gcc -o line line.c
Aufruf mit

Code: Alles auswählen

export COLUMNS
kommando | ./line
Die Umgebungsvariable COLUMNS muss exportiert werden, damit die Terminalbreite erkannt werden kann, andernfalls gibt es eine Segmentation Fault.
Das Programm wurde mit find getestet.

Gruß, lhfloss

Fjunchclick

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von Fjunchclick » 16.07.2012 11:46:59

Hallo lhfloss,
vielen Dank für deine Mühe. Kompilieren hat geklappt, leider funktioniert es aber nicht. Es gibt keinen Unterschied, ob ich das Programm mit aufrufe oder nicht. Der Text scrollt trotzdem ganz normal durch, eine Fehlermeldung gibt es auch nicht. Das Programm befindet sich natürlich im richtigen Verzeichnis.

Ich habe das mal mit einer Partition getestet, in der nur wenige Dateien sind, damit die Ausgaben nicht aus dem Fenster scrollen.
Hier mal die Terminalausgabe zur Verdeutlichung:

Code: Alles auswählen

root@farnsworth:/home/lars# export COLUMNS
root@farnsworth:/home/lars# fsarchiver savefs -o -j2 -A -a -v -z3 /usr/local/Daten/farnsworth_image.fsa /dev/sdb2 | ./line
Analysing filesystem on /dev/sdb2...
============= archiving filesystem /dev/sdb2 =============
-[00][  0%][DIR     ] /
-[00][  0%][REGFILEM] /line.c
-[00][  0%][REGFILEM] /line
-[00][  0%][DIR     ] /lost+found
-[00][  1%][DIR     ] /Wallpapers
-[00][ 11%][REGFILE ] /Wallpapers/1249-1920x1200.jpg
-[00][ 31%][REGFILE ] /Wallpapers/02712_multnomahfalls_1366x768.jpg
-[00][ 59%][REGFILE ] /Wallpapers/02029_venetianroads_1400x1050.jpg
-[00][ 66%][REGFILE ] /Wallpapers/02141_auroraborealis_1366x768.jpg
-[00][ 74%][REGFILE ] /Wallpapers/1093-2000x1333a.jpg
-[00][ 77%][REGFILE ] /Wallpapers/1280px-Caspar_David_Friedrich_-_Mondaufgang_am_Meer_-_Google_Art_Project.jpg
-[00][ 91%][REGFILE ] /Wallpapers/2022-2560x1600.jpg
-[00][ 99%][REGFILE ] /Wallpapers/1093-2000x1333.jpg
-[00][100%][DIR     ] /.Trash-1000
Statistics for filesystem 0
* files successfully processed:....regfiles=10, directories=4, symlinks=0, hardlinks=0, specials=0
* files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0

root@farnsworth:/home/lars# 

Die Zeilen zwischen "============= archiving filesystem /dev/sdb2 ============="
und "Statistics for filesystem 0" sind die, um die es geht. Das ist das, was durch den Schalter -v im Kommando ausgegeben wird. Sind es mehr Dateien, scrollen diese Ausgaben eben über den Bildschirm. Lässt man den Schalter weg, passiert während der Sicherung nichts und am Ende wird die Statistik ausgegeben:

Code: Alles auswählen

root@farnsworth:/home/lars# fsarchiver savefs -o -j2 -A -a -z3 /usr/local/Daten/farnsworth_image.fsa /dev/sdb2 | ./line
Statistics for filesystem 0
* files successfully processed:....regfiles=10, directories=4, symlinks=0, hardlinks=0, specials=0
* files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0

root@farnsworth:/home/lars# 
Da so eine Sicherung aber locker mal 10 Minuten dauern kann, ist es einfach blöd, wenn entweder wie wild gescrollt wird oder man gar nichts sieht.
Scheint aber gar nicht so einfach zu sein.

Ich glaube, das Problem besteht darin, dass es ja nicht um die eigentliche Ausgabe des Befehls geht, sondern nur um das, was fsarchiver während der Ausführung durch den verboose-Modus (-v) mitteilt, kann das sein?
Zuletzt geändert von Fjunchclick am 16.07.2012 11:49:57, insgesamt 1-mal geändert.

lhfloss
Beiträge: 261
Registriert: 07.10.2007 21:02:15
Lizenz eigener Beiträge: MIT Lizenz

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von lhfloss » 16.07.2012 11:49:26

Vielleicht schreibt fsarchiver seine Ausgabe auf stderr. In dem Fall muss der Programmaufruf ergänzt werden:

Code: Alles auswählen

fsarchiver [...] 2>&1 | ./line

Fjunchclick

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von Fjunchclick » 16.07.2012 11:52:54

Yes!!!
Das war es!
Wow, vielen, vielen Dank! Jetzt kann ich weiter an meinem Skript basteln.

Danke auch nochmals an Liffi und WPSchulz.

:hail:

lemak
Beiträge: 1213
Registriert: 09.11.2007 13:25:57
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Shell-Skript - Frage zur Ausgabe

Beitrag von lemak » 16.07.2012 13:12:39

lhfloss hat geschrieben:Ich hab gestern mal ein bisschen in C herumprobiert ...
Das ginge auch mit einer Bash-Funktion:

Code: Alles auswählen

#! /bin/bash

function line
{
	while read zeile; do
		printf "%-71s" "$zeile"

		if [[   "$zeile" =~ ^-\[[[:digit:]]+\]\[[\ ]*[[:digit:]]+%\]\[ ]] \
		&& [[ ! "$zeile" =~ ^-\[[[:digit:]]+\]\[100%\]\[               ]]; then
			printf "\r"
		else
			printf "\n"
		fi
	done
}

fsarchiver [...] 2>&1 | line
Der Regex könnte sicher besser sein und lässt man den weg, läuft es auch mit der dash bzw. /bin/sh.

Die Ausgabe:

Code: Alles auswählen

$ bash /Pfad/zum/Skript.sh
Analysing filesystem on /dev/sdb2...                                   
============= archiving filesystem /dev/sdb2 =============             
-[00][100%][DIR     ] /.Trash-1000                                     ufgang_am_Meer_-_Google_Art_Project.jpg
Statistics for filesystem 0                                            
* files successfully processed:....regfiles=10, directories=4, symlinks=0, hardlinks=0, specials=0
* files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0
Zuletzt geändert von lemak am 16.07.2012 15:15:52, insgesamt 11-mal geändert.

Fjunchclick

Re: [gelöst] Shell-Skript - Frage zur Ausgabe

Beitrag von Fjunchclick » 16.07.2012 14:00:25

Cool, danke!
Werde ich heute abend gleich ausprobieren, wenn ich wieder zu hause bin.

WPSchulz
Beiträge: 264
Registriert: 19.12.2010 17:13:53
Wohnort: Germany/ Dietzenbach
Kontaktdaten:

Re: [gelöst] Shell-Skript - Frage zur Ausgabe

Beitrag von WPSchulz » 16.07.2012 17:43:14

Bei der Lösung von WPSchulz weiß ich leider auch nicht so recht, wie ich das für mein Anliegen umsetzen muss.
Der Trick besteht darin, die verbose-Ausgabe eines Befehls in einer Pipe weiter zu verabeiten, sowie abschliessend formatiert auszugeben.
Ein etwas einfacheres Beispiel aus meinen Script darüber:

Code: Alles auswählen

rm -vR /opt/knx | sed 's/\/opt\/knx//' \
| awk '{printf "%-78s\r", substr($1, 1, 78)}'
Das Verzeichnis '/opt/knx' soll rekursiv gelöscht werden.
"sed" ersetzt den Teil '/opt' durch nichts.
"substr" bildet aus dem String $1 einen Teilstring
"printf" gibt diesen Teilstring formattiert aus: linksbündig, maximal 78 Zeichen, anschliessend "Carriage return"; das Ganze dann an "awk" übergeben.
Ich habe 78 Zeichen gewählt, weil die Terminalbreite in der Regel 80 Zeichen beträgt. Man kann natürlich auch weniger als 78 Zeichen bei substr und printf eintragen, dafür sed sagen, daß in diesem Beispiel '/opt' durch zwei Leerzeichen ersetzt wird; dann klebt die Ausgabe nicht am linken Rand. Wenn Du noch

Code: Alles auswählen

setterm -cursor off bzw on
benutzt, ist auch kein hin- und herflitzender Block-Cursor zu sehen.
Gruss Werner * Eigene Rescue-CD
Grml remaster
Knoppix remaster

Antworten