ubuntuusers.de

Bash Script: inscape export ausgabe unterdrücken und progressbar hinzufügen

Status: Ungelöst | Ubuntu-Version: Ubuntu MATE 21.10 (Impish Indri)
Antworten |

JoeJoke

Anmeldungsdatum:
21. Dezember 2015

Beiträge: Zähle...

Moin,

Ich möchte an einer Stelle meines Scripts .svg Dateien mit dem Befehl

1
find -name "*.svg" -exec sh -c 'inkscape $1 --export-dpi=300 --export-type="png"' _ {} \

in .png Dateien exportieren. Da es sich um eine Stapelverarbeitung geht möchte ich dort eine Progressbar hinzufügen. Hab dazu diese hier gefunden: https://stackoverflow.com/questions/238073/how-to-add-a-progress-bar-to-a-shell-script?page=1&tab=votes#tab-top

 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
# 1. Create ProgressBar function
# 1.1 Input is currentState($1) and totalState($2)
function ProgressBar {
# Process data
    let _progress=(${1}*100/${2}*100)/100
    let _done=(${_progress}*4)/10
    let _left=40-$_done
# Build progressbar string lengths
    _fill=$(printf "%${_done}s")
    _empty=$(printf "%${_left}s")

# 1.2 Build progressbar strings and print the ProgressBar line
# 1.2.1 Output example:                           
# 1.2.1.1 Progress : [########################################] 100%
printf "\rProgress : [${_fill// /#}${_empty// /-}] ${_progress}%%"

}


# Variables
_start=1

# This accounts as the "totalState" variable for the ProgressBar function
_end=100

# Proof of concept
for number in $(seq ${_start} ${_end})
do
    sleep 0.1
    ProgressBar ${number} ${_end}
done
printf '\nFinished!\n'

Mein erstes Problem ist erstmal wenn ich die Ausgabe mit > /dev/null unterdrücken möchte funktioniert dies nicht. Trotz Umleitung wird der entsprechende export in der Shell dennoch ausgegeben. Wie genau kann ich in dem Fall die Shellausgabe unterdrücken.

Falls jemand zum anschließenden Progressbar hinzufügen einen Tipp geben kann, wie ich die obige Funktion einfügen kann wäre es auch super. Aber zu allererst wäre das unterdrücken der Ausgabe erstmal am wichtigsten.

Danke schonmal im vorraus.

Greetz

shiro Team-Icon

Supporter

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1269

Hallo JoeJoke,

so ganz verstehe ich dein Problem nicht. In deinem bash script definierst du die function ProgressBar wie im Beispiel. In der Schleife, wo du deinen Ausgabe machen willst, ersetzt du

# statt
$ ProgressBar ${number} ${_end}
# nun 
$ ProgressBar ${number} ${_end} >/dev/null

JoeJoke

(Themenstarter)

Anmeldungsdatum:
21. Dezember 2015

Beiträge: 11

Dann hast du mein eigentliches Problem missverstanden. Die Progressbar ist ne andere Geschichte, die jetzt erstmal uninteressant ist. Geht eigentlich eher um die Ausgabe von Inkscape, die Progressbar soll nur eingefügt werden am Ende. Und bei dem Inkscape liegt halt das Problem. Mit >/dev/null kann ich die Ausgabe so nicht umleiten. Es werden weiterhin alle Dinge ausgegeben die auch ohne ausgegeben werden. Die Ausgabe selbst wird als nicht nach /dev/null umgeleitet sondern weiterhin in die Console.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Wohnort: Göttingen

Schau Dir mal Shell/Umleitungen an.

Das hier sollte funktionieren:

 &>/dev/null

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Inkscape dürfte Meldungen auf stderr statt stdout ausgeben - hast du mal versucht den umzuleiten (vgl. Shell/Umleitungen)?

find -name "*.svg" -exec sh -c 'inkscape $1 --export-dpi=300 --export-type="png"' _ {} \ 2>/dev/null 

Da die shell von find für jede Datei neu erstellt und dann wieder zerstört wird, kann man sich überlegen, ob man das nicht umdreht, so dass es eine for-Loop in einer ständig laufenden Shell wird:

1
2
3
4
while IFS= read -r -d $'\0' file
do
    inkscape  "$file" --export-dpi=300 --export-type="png" 2>/dev/null
done < <(ind -name "*.svg" -print0)

Für eine Fortschrittsanzeige ist es hilfreich vorarb zu wissen, wie viele Dateien es insgesamt gibt, die verarbeitet werden sollen, also könnte man die Pfade in ein Array einlesen:

1
2
3
4
5
6
7
8
IFS= readarray -d $'\0' svg_paths < <(find -name "*.svg" -print0)
n_elements="${#svg_paths[@]}"

for idx in "${!svg_paths[@]}"
do
    inkscape "${svg_paths[$idx]}" --export-dpi=300 --export-type="png" 2> /dev/null
    ProgressBar $(( idx + 1 )) "$n_elements"
done

JoeJoke

(Themenstarter)

Anmeldungsdatum:
21. Dezember 2015

Beiträge: 11

seahawk1986 Werd des später mal testen ob ich das ganze so umgeleitet kriege. Aber dank dir schon mal.

Und was die Fortschrittanzeige anzeige angeht wird es wohl eher schwierig mit nem Array. Zur Erklärung: Mit dem Script wird eine .svg Datei x mal dupliziert, dort werden bestimmte Daten, zb Texte oder Farben, geändert (zb die erste datei 1, die 2. 2, die 3. 3 usw) und zum Abschluss wird jede .svg Datei in .png exportiert. Bedeutet es könnten 2 Dateien sein, es könnten 30 Dateien sein, es könnten aber auch 100+ Dateien sein. Dies wird ganz zu anfang via User Eingabe deklariert. Bin am überlegen das ganze dann über die .png Dateien zu regeln indem ich diese in dem Ordner zählen lasse und darüber dann die Progressbar zu erstellen. Mal schauen. Aber Arrays schließe ich in dem Fall gänzlich aus.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

Du kannst das auch gleich mit gm (GraphicsMagick, ähnlich zu ImageMagick) machen - das ist ein Kommandozeilenwerkzeug mit tonnenweise Funktionalitäten. Beispiel:

1
gm convert -monitor -geometry 300x400 input.svg output.png
Antworten |