ubuntuusers.de

Bash Script Funktion abbrechen und neue starten (ähnlich goto)

Status: Gelöst | Ubuntu-Version: Kubuntu 8.04 (Hardy Heron)
Antworten |

darklord

Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hallo ☺

Ich habe ein kleines Problem mit einem meiner Bash Scripte!
Ich habe dort mehrere Funktionen. Je nach "Arbeit" des Scriptes kann es vorkommen, dass ich innerhalb einer Funktion eine andere aufrufe.
Soweit so gut... wenn ich dann nach beenden der neu aufgerufenen Funktion wieder eine Funktion aufrufe, sei es die selbe wie vorher oder eine andere, macht er an der Stelle weiter, wo vorher der Funktionsaufruf erfolgte. Meine Frage also:

Wie kann ich aus einer Funktion heraus eine andere aufrufen und die vorangehende praktisch "beenden", so dass, wenn ich diese dann wieder erneut aufrufe, die Funktion von vorne abgearbeitet wird?

Hier ein Beispiel was ich meine, die Syntax in den if-Abfragen ist nicht richtig - ich weiß, dient ja auch nur als Beispiel ☺

 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
#!/bin/bash

function test1 {
if bla=blubb; then
echo hallo welt
exit
fi
test3
echo och }

function test2 {
if blubb -eq 3; then
echo auf wiedersehen
exit
fi
test1
}

function test3 {
if blubb=0; then
echo schallalala
test1
}

test1

exit 0

Laut diesem Beispiel möchte ich, wenn if nicht gegeben ist, die Funktion test3 aufrufen. Das passiert auch. Wenn dann test3 durch ist, wird wieder test1 aufgerufen. Diese soll dann aber wieder von vorne anfangen, aber er macht dann nach dem aufruf test3 weiter und gibt dann gleich och nö aus, anstatt erstmal nach hallo welt zu prüfen.

Ich hoffe, es ist deutlich geworden, was mein Problem ist ☺

Die Frage nochmal kurz und bündig zusammengefasst:
Wie kann ich aus test1 die Funktion test3 aufrufen und gleichzeitig test1 so abschliessen, dass beim nächsten Funktionsaufruf test1 wieder von vorne "anläuft" und nicht an der Stelle weitergemacht wird, von wo die nächste Funktion aufgerufen wurde?

Gruß Dark

pinguino

Avatar von pinguino

Anmeldungsdatum:
6. Februar 2007

Beiträge: 732

Wohnort: BW

du könntest das mit

return

lösen, wobei 0 (Ok!) und 1 (Nicht Ok!)

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hallo ☺

Hm ja das hatte ich schon probiert, aber es nicht genau hinbekommen. Wo genau muss denn das return in meinem Beispiel hin?

Gruß Dark

pinguino

Avatar von pinguino

Anmeldungsdatum:
6. Februar 2007

Beiträge: 732

Wohnort: BW

so z.B

afunktion () {

Befehl 1

Befehl 2

...

return 0

Befehl 3

}

Befehl 3 wird dann nicht ausgeführt

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hm ja das weiss ich, aber bei mir beendet er dann das ganze Script!

Hier mal nen Codeschnipsel aus meinem Script:

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/bin/bash

function hauptprogramm {
if ! AKTION=$(kdialog --title "PDF Bearbeitung" --menu "Aktion auswählen:" pdfjoin "PDF zusammenfügen" pdfburst "PDF aufteilen"); then
	exit;
fi
}

function pdfjoin {
if ! PFAD=$(/usr/bin/$DIALOG --title "Ordner mit den zusammenzufügenden PDF-Dateien wählen" --getexistingdirectory "$USERPFAD"); then
	hauptprogramm;
fi
ANZAHL=$(ls "$PFAD"/*.pdf | wc -l)
if [ $ANZAHL == 1 ]; then
	/usr/bin/$DIALOG --error "In dem Ordner befindet sich nur eine PDF-Datei!"
	pdfjoin;
elif [ $ANZAHL == 0 ]; then
	/usr/bin/$DIALOG --error "In dem Ordner befinden sich keine PDF-Dateien!"
	pdfjoin;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
	hauptprogramm;
fi
cd "$PFAD"
pdftk *.pdf cat output "$SPEICHERN"
}

function pdfburst {
if ! DATEI=$(/usr/bin/$DIALOG --title "Aufzuteilende PDF-Datei auswählen" --getopenfilename "$USERPFAD"); then
	hauptprogramm;
fi
if [ $(pdfinfo $DATEI | grep Pages | head -6 | tail -1 | awk '{print $2}') == 1 ]; then
	/usr/bin/$DIALOG --error "Die ausgewählte PDF-Datei hat nur eine Seite, aufteilen ist nicht möglich!"
	pdfburst;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die einzelnen PDF-Dateien erstellt werden?" --getexistingdirectory "$USERPFAD"); then
	hauptprogramm;
fi
cd "$SPEICHERN"
pdftk "$DATEI" burst
rm doc_data.txt
}

hauptprogramm

if [ "$AKTION" = "pdfjoin" ]; then
	pdfjoin
fi

if [ "$AKTION" = "pdfburst" ]; then
	pdfburst
fi

exit 0

Wenn ich das Script starte, wird das Hauptprogramm gestartet und ich kann wählen.

Wähle ich Aufteilen, wird der Ordnerauswahldialog geöffnet. Gehe ich dann auf abbrechen, springt er wieder zurück ins Hauptprogramm (von Zeile 11 nach Zeile 3). So weit so gut. Wenn ich im Hauptprogramm jetzt allerdings PDF aufteilen wähle, macht er nach der Ordnerwahl von der ersten Funktion weiter (Zeile 13ff) und es kommt der Errordialog, das keine PDF im Ordner ist. Genau HIER liegt das Problem. Der soll da wieder in der Funktion pdfjoin von vorne anfangen (von Zeile 11 über Zeile 3ff nach Zeile 28ff (oder 9ff, je nach Auswahl), aber NICHT bei Zeile 13ff weitermachen) und mir wieder die Ordnerwahl öffnen, also nicht nach dem Sprung zum Hauptprogramm zurück in die zuerst gestartete Funktion gehen und an der Stelle weitermachen.

Deutlich, was ich meine?

Wie könnte ich das in meinem Script bewerkstelligen?

Gruß Dark

pinguino

Avatar von pinguino

Anmeldungsdatum:
6. Februar 2007

Beiträge: 732

Wohnort: BW

du müßtest das anders machen, da Bash kein "Goto" kennt.

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hm und wie kann ich das machen? Mit bash dann gar nicht oder auf ne andere Art und Weise wie ich das jetzt gemacht habe?

pinguino

Avatar von pinguino

Anmeldungsdatum:
6. Februar 2007

Beiträge: 732

Wohnort: BW

du könntest mit einer Schleife arbeiten z.B

while true

do

....


done

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Uff, ich stehe gerade aber sowas von auf dem Schlauch xD

Wo baue ich die denn ein? Nach dem Motto:

while true do

function pdfjoin
funktionsaufruf hauptprogramm

done

Ich kann mir jetzt nicht wirklich vorstellen, wie dann der Rücksprung verhindert werden soll... Bitte hilf mir auf die Sprünge ^^

Nachtrag:
Oder sowas wie
function pdfjoin
{
while check=true do
if cancel
check=false
done
hauptprogramm
}

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hey, den Schritt ins Hauptmenü bei Abbrechen habe ich geschafft ☺

Nach meiner Variante kann ich jetzt nicht bei nem Unter-Unter-Menü zurück ins Unter-Menü springen, sondern nur ins Hauptmenü, aber das passt so schon ganz gut!

Ich habe es wie folgt gelöst:

 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
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/bash

function hauptprogramm {
if ! AKTION=$(kdialog --title "PDF Bearbeitung" --menu "Aktion auswählen:                          " pdfjoin "PDF zusammenfügen" pdfburst "PDF aufteilen" pdfturn "PDF drehen" pdfcrypt "PDF verschlüsseln" pdfdecrypt "PDF entschlüsseln" pdfimages "Bilder extrahieren" pdfcrack "Passwort knacken"); then
	exit;
fi
aktionen
}

function aktionen {
	if [ "$AKTION" = "pdfjoin" ]; then
		if ! PFAD=$(/usr/bin/$DIALOG --title "Ordner mit den zusammenzufügenden PDF-Dateien wählen" --getexistingdirectory "$USERPFAD"); then
			hauptprogramm;
		fi
		ANZAHL=$(ls "$PFAD"/*.pdf | wc -l)
		if [ $ANZAHL == 1 ]; then
			/usr/bin/$DIALOG --error "In dem Ordner befindet sich nur eine PDF-Datei!"
			hauptprogramm;
		elif [ $ANZAHL == 0 ]; then
			/usr/bin/$DIALOG --error "In dem Ordner befinden sich keine PDF-Dateien!"
			hauptprogramm;
		fi
		if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
			hauptprogramm;
		fi
		cd "$PFAD"
		pdftk *.pdf cat output "$SPEICHERN"
	fi
	if [ "$AKTION" = "pdfburst" ]; then
		if ! DATEI=$(/usr/bin/$DIALOG --title "Aufzuteilende PDF-Datei auswählen" --getopenfilename "$USERPFAD"); then
			hauptprogramm;
		fi
		if [ $(pdfinfo $DATEI | grep Pages | head -6 | tail -1 | awk '{print $2}') == 1 ]; then
			/usr/bin/$DIALOG --error "Die ausgewählte PDF-Datei hat nur eine Seite, aufteilen ist nicht möglich!"
			hauptprogramm;	
		fi
		if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die einzelnen PDF-Dateien erstellt werden?" --getexistingdirectory "$USERPFAD"); then
			hauptprogramm;
		fi
		cd "$SPEICHERN"
		pdftk "$DATEI" burst
		rm doc_data.txt
	fi
}


hauptprogramm

exit 0

So kommt er nicht dazu, zur ersten Funktion zurückzuspringen, weil in der Funktion schon wieder eine neue aufgerufen wird. Es ist praktisch eine Funktion-Endlosschleife, die mit Programmende durch exit unterbrochen wird.

Falls noch eine elegantere Lösung existiert, wo ich auch von einem Unter-Unter-Menü zurück in ein Unter-Menü springen kann - das geht ja nicht, da ich nur zwei Funktionen verwenden kann momentan, da ich aus dem Hauptmenü ja nur immer die gleiche Funktion aufrufen kann - dann bitte bescheid geben ^^

Vielleicht fällt mir auch selbst noch eine Lösung ein, ich melde mich dann.

Pinguino, vielen Dank für Deine Hilfe bisher!

Gruß Dark

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Lösung für mich gefunden:

 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
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/bash

function hauptprogramm {
if ! AKTION=$(kdialog --title "PDF Bearbeitung" --menu "Aktion auswählen:                          " pdfjoin "PDF zusammenfügen" pdfburst "PDF aufteilen" pdfturn "PDF drehen" pdfdecrypt "PDF entschlüsseln" pdfcrypt "PDF verschlüsseln" pdfimages "Bilder extrahieren" pdfcrack "Passwort knacken"); then
	exit;
fi
$AKTION
}

function pdfjoin {
if ! PFAD=$(/usr/bin/$DIALOG --title "Ordner mit den zusammenzufügenden PDF-Dateien wählen" --getexistingdirectory "$USERPFAD"); then
	hauptprogramm;
fi
ANZAHL=$(ls "$PFAD"/*.pdf | wc -l)
if [ $ANZAHL == 1 ]; then
	/usr/bin/$DIALOG --error "In dem Ordner befindet sich nur eine PDF-Datei!"
	pdfjoin;
elif [ $ANZAHL == 0 ]; then
	/usr/bin/$DIALOG --error "In dem Ordner befinden sich keine PDF-Dateien!"
	pdfjoin;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
	pdfjoin;
fi
cd "$PFAD"
pdftk *.pdf cat output "$SPEICHERN"
exit
}

function pdfburst {
if ! DATEI=$(/usr/bin/$DIALOG --title "Aufzuteilende PDF-Datei auswählen" --getopenfilename "$USERPFAD"); then
	hauptprogramm;
fi
if [ $(pdfinfo $DATEI | grep Pages | head -6 | tail -1 | awk '{print $2}') == 1 ]; then
	/usr/bin/$DIALOG --error "Die ausgewählte PDF-Datei hat nur eine Seite, aufteilen ist nicht möglich!"
	pdfburst;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die einzelnen PDF-Dateien erstellt werden?" --getexistingdirectory "$USERPFAD"); then
	pdfburst;
fi
cd "$SPEICHERN"
pdftk "$DATEI" burst
rm doc_data.txt
exit
}

hauptprogramm

exit 0

So springt er aus einem "Unteruntermenü" nicht ins Hauptmenü zurück, sondern gleich wieder zum Anfang der betreffenden Funktion. Also wenn ich beim ersten Dialog der Funktion abbreche, springt er ins Hauptmenü zurück, breche ich später in der Funktion irgendwann ab, springt er zum Anfang der Funktion. Genauso wollte ich das haben, also praktisch eine Art selbstbau-goto für bash ^^

Danke für die Hilfe

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4673

Wohnort: Berlin

@darklord: Das ist aber keine saubere Lösung weil Du immer neue Funktionen anfängst, die nie zuende geführt werden. Damit müllst Du den Aufrufstapel voll. Ob und wann das zu einem Problem wird, kann ich nicht sagen, aber schön ist das nicht.

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hm ja, das ist mir bewusst, aber ne andere Lösung hab ich bislang nicht gefunden. Da im Script aber eigentlich nicht unbegrenzt hin und her "gesprungen" wird, sondern man ja eigentlich gleich die richtige Aktion startet (aber halt mal im Notfall doch zurück kann um was anderes zu wählen), sollte das kein Problem werden. Ist ja nach ein paar Funktionsaufrufen dann beendet, wenn die gewünschte Aktion ausgeführt wird.

Falls jemandem eine Saubere Lösung einfällt, bitte posten ☺

Hier mein ganzes Script:

  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
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#! /bin/bash

USERPFAD="/home/$USER"

if [ -f "$(which kdialog)" ]; then
	DIALOG=kdialog
else
	if [ -f "$(which zenity)" ]; then
		DIALOG=zenity
	else
		DIALOG=gdialog
	fi
fi

which pdftk pdfimages > /dev/null
if [ $? -eq 1 ]; then
	if /usr/bin/$DIALOG --title "Paketabhängigkeit" --warningcontinuecancel "Es muss mindestens ein fehlendes Paket installiert werden!"; then
		konsole -e sudo apt-get install pdftk xpdf-utils
		which pdftk pdfimages pdfcrack > /dev/null
		if [ $? -eq 1 ]; then
			/usr/bin/$DIALOG --error "Fehler beim installieren des Paketes!\n Bitte manuell überprüfen, ob pdftk und pdfimages installiert sind und ggf. installieren."
		exit;
		fi
	else
		exit;
	fi
fi

function hauptprogramm {
if ! AKTION=$(/usr/bin/$DIALOG --title "PDF Bearbeitung" --menu "Aktion auswählen:                          " pdfjoin "PDF zusammenfügen" pdfburst "PDF aufteilen" pdfturn "PDF drehen" pdfdecrypt "PDF entschlüsseln" pdfcrypt "PDF verschlüsseln" pdfimages "Bilder extrahieren"); then
	exit;
fi
$AKTION
}

function pdfjoin {
if ! PFAD=$(/usr/bin/$DIALOG --title "Ordner mit den zusammenzufügenden PDF-Dateien wählen" --getexistingdirectory "$USERPFAD"); then
	hauptprogramm;
fi
ANZAHL=$(ls "$PFAD"/*.pdf | wc -l)
if [ $ANZAHL == 1 ]; then
	/usr/bin/$DIALOG --error "In dem Ordner befindet sich nur eine PDF-Datei!"
	pdfjoin;
elif [ $ANZAHL == 0 ]; then
	/usr/bin/$DIALOG --error "In dem Ordner befinden sich keine PDF-Dateien!"
	pdfjoin;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
	pdfjoin;
fi
cd "$PFAD"
pdftk *.pdf cat output "$SPEICHERN"
exit
}

function pdfburst {
if ! DATEI=$(/usr/bin/$DIALOG --title "Aufzuteilende PDF-Datei auswählen" --getopenfilename "$USERPFAD"); then
	hauptprogramm;
fi
if [ $(pdfinfo $DATEI | grep Pages | head -6 | tail -1 | awk '{print $2}') == 1 ]; then
	/usr/bin/$DIALOG --error "Die ausgewählte PDF-Datei hat nur eine Seite, aufteilen ist nicht möglich!"
	pdfburst;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die einzelnen PDF-Dateien erstellt werden?" --getexistingdirectory "$USERPFAD"); then
	pdfburst;
fi
cd "$SPEICHERN"
pdftk "$DATEI" burst
rm doc_data.txt
exit
}

function pdfturn {
if ! DATEI=$(/usr/bin/$DIALOG --title "Zu drehende PDF-Datei auswählen" --getopenfilename "$USERPFAD" *.pdf); then
	hauptprogramm;
fi
if ! DREHEN=$(/usr/bin/$DIALOG --title "PDF drehen" --menu "Wie soll gedreht werden?" A1L "90° Linksdrehung" A1R "90° Rechtsdrehung" A1D "180° Drehung"); then
	pdfturn;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
	pdfturn;
fi
pdftk A="$DATEI" cat $DREHEN output "$SPEICHERN"
if [ $? -eq 1 ]; then
	/usr/bin/$DIALOG --error "Start- und Zieldatei sind identisch!\n Bitte unter einem anderen Namen speichern."
	pdfturn;
fi
exit
}

function pdfdecrypt {
if ! DATEI=$(/usr/bin/$DIALOG --title "Passwortgeschütze PDF auswählen - Passwort muss bekannt sein!" --getopenfilename "$USERPFAD" *.pdf); then
	hauptprogramm;
fi
if ! PASSWORT=$(/usr/bin/$DIALOG --title "Passwort entfernen" --password "Bitte geben Sie das Passwort der PDF-Datei ein:"); then
	pdfdecrypt;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
	pdfdecrypt;
fi
pdftk "$DATEI" input_pw "$PASSWORT" output "$SPEICHERN"
if [ $? -eq 1 ]; then
	/usr/bin/$DIALOG --error "Start- und Zieldatei sind identisch!\n Bitte unter einem anderen Namen speichern."
	pdfdecrypt;
fi
exit
}

function pdfcrypt {
if ! DATEI=$(/usr/bin/$DIALOG --title "PDF auswählen, die verschlüsselt  werden soll" --getopenfilename "$USERPFAD" *.pdf); then
	hauptprogramm;
fi
if ! PASSWORT=$(/usr/bin/$DIALOG --title "Besitzer-Passwort hinzufügen" --password "Bitte geben Sie das gewünschte Passwort ein:"); then
	pdfcrypt;
fi
USERPASSWORT=""
if /usr/bin/$DIALOG --title "Passwortschutz" --yesno "Soll ein Passwort zum öffnen der PDF-Datei erforderlich sein?"; then
	if ! PASSWORT2=$(/usr/bin/$DIALOG --title "Benutzer-Passwort hinzufügen" --password "Bitte geben Sie das gewünschte Passwort ein:"); then
		pdfcrypt;
	fi
USERPASSWORT="user_pw $PASSWORT2"
fi
if ! OPTIONEN=$(/usr/bin/$DIALOG --title "PDF Optionen" --separate-output --checklist "Bitte auswählen, wenn was in der PDF-Datei erlaubt sein soll:" "allow Printing" "Drucken" off "allow ModifyContents" "Inhalt verändern" off "allow CopyContents" "Inhalt kopieren" off "allow ModifyAnnotations" "Kommentare hinzufügen" off); then
	pdfcrypt;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
	pdfcrypt;
fi
pdftk "$DATEI" output "$SPEICHERN" owner_pw $PASSWORT $USERPASSWORT $OPTIONEN
if [ $? -eq 1 ]; then
	/usr/bin/$DIALOG --error "Start- und Zieldatei sind identisch!\n Bitte unter einem anderen Namen speichern."
	pdfcrypt;
fi
exit
}

function pdfimages {
if ! DATEI=$(/usr/bin/$DIALOG --title "PDF-Datei auswählen, aus welcher die Bilder extrahiert werden sollen" --getopenfilename "$USERPFAD" *.pdf); then
	hauptprogramm;
fi
if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die Bilder gespeichert werden?" --getexistingdirectory "$USERPFAD"); then
	pdfimages;
fi
pdfimages "$DATEI" "$SPEICHERN"/
exit
}

hauptprogramm

exit 0

Gruß Dark

Hello_World

Anmeldungsdatum:
13. Juni 2006

Beiträge: 3620

Zwei Bemerkungen: Erstens kann ich das im Eingangsposting beschriebene Problem nicht nachvollziehen. Folgendes wäre, wenn ich Deine Beschreibung richtig verstehe, ein Minimalbeispiel:

1
2
3
4
5
6
7
8
9
#!/bin/bash
function x {
    y
    echo foo
}
function y {
    x
}
x

Hier ruft x y auf, welches wiederrum x aufruft. Wenn Deine Beschreibung zuträfe, müsste nun foo ausgegeben werden, was aber nicht mit der Realität übereinstimmt. Bitte liefere uns ein möglichst kurzes und syntaktisch korrektes Script, das das Problem demonstriert, so dass wir es nachvollziehen und klären können.

Zweitens setzt Du Funktionen hier auf wenig sinnvolle Art und Weise ein. Funktionen sind keine Sprungmarken, die einfach dazu dienen, irgendwie im Programm herumzuhüpfen; Eine Funktion sollte genau eine Aufgabe erfüllen und nach deren Ausführung oder der Feststellung eines Fehlers zurückkehren. Diese Regel verletzt Du, indem Du z. B. in pdfburst nach der Festellung eines Fehlers nicht zurückkehrst, sondern hauptprogramm erneut aufrufst. Eine saubere Lösung sähe so aus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function pdfburst {
    while true; do
        if ! DATEI=$(/usr/bin/$DIALOG --title "Aufzuteilende PDF-Datei auswählen" --getopenfilename "$USERPFAD"); then
            return
        fi
        if [ $(pdfinfo $DATEI | grep Pages | head -6 | tail -1 | awk '{print $2}') == 1 ]; then
            /usr/bin/$DIALOG --error "Die ausgewählte PDF-Datei hat nur eine Seite, aufteilen ist nicht möglich!"
            continue
        fi
        if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die einzelnen PDF-Dateien erstellt werden?" --getexistingdirectory "$USERPFAD"); then
            continue
        fi
        break
    done
    cd "$SPEICHERN"
    pdftk "$DATEI" burst
    rm doc_data.txt
    exit
}

Das Schlüsselwort continue springt zurück an den Anfang der while-Schleife, während return die Funktion verlässt. Was nach der Festellung eines Fehlers passiert, geht pdfburst nichts an, darum muss sich hauptprogramm kümmern:

1
2
3
4
5
6
function hauptprogramm {
    while AKTION=$(/usr/bin/$DIALOG --title "PDF Bearbeitung" --menu "Aktion auswählen:                          " pdfjoin "PDF zusammenfügen" pdfburst "PDF aufteilen" pdfturn "PDF drehen" pdfdecrypt "PDF entschlüsseln" pdfcrypt "PDF verschlüsseln" pdfimages "Bilder extrahieren") && ! $AKTION
    do
        true
    done
}

darklord

(Themenstarter)
Avatar von darklord

Anmeldungsdatum:
10. April 2007

Beiträge: 235

Hey Hello World,

vielen Dank schon mal für die ausführliche Erklärung. Habe es natürlich gleich eingebaut und das funktioniert auch soweit echt super. Keine Endlos-Funktionsaufrufe mehr xD

Allerdings ist mir aufgefallen, dass immer, wenn ich am Anfang einer Funktion abbrechen drücke, also dieses return zum tragen kommt, gleich das ganze Programm geschlossen wird. Noch ne Idee, wie ich das Hauptprogramm wieder öffnen lassen kann oder was ich bei der Hauptprogrammschleife noch einbauen muss, damit die dann nicht beendet wird, wenn nen return kommt?

Gruß Dark

Hier mein aktualisiertes Script:

  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
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#! /bin/bash

USERPFAD="/home/$USER"

if [ -f "$(which kdialog)" ]; then
	DIALOG=kdialog
else
	if [ -f "$(which zenity)" ]; then
		DIALOG=zenity
	else
		DIALOG=gdialog
	fi
fi

which pdftk pdfimages > /dev/null
if [ $? -eq 1 ]; then
	if /usr/bin/$DIALOG --title "Paketabhängigkeit" --warningcontinuecancel "Es muss mindestens ein fehlendes Paket installiert werden!"; then
		konsole -e sudo apt-get install pdftk xpdf-utils
		which pdftk pdfimages pdfcrack > /dev/null
		if [ $? -eq 1 ]; then
			/usr/bin/$DIALOG --error "Fehler beim installieren des Paketes!\n Bitte manuell überprüfen, ob pdftk und pdfimages installiert sind und ggf. installieren."
		exit;
		fi
	else
		exit;
	fi
fi

function hauptprogramm {
while AKTION=$(/usr/bin/$DIALOG --title "PDF Bearbeitung" --menu "Aktion auswählen:                          " pdfjoin "PDF zusammenfügen" pdfburst "PDF aufteilen" pdfturn "PDF drehen" pdfdecrypt "PDF entschlüsseln" pdfcrypt "PDF verschlüsseln" pdfimages "Bilder extrahieren")  && ! $AKTION
do
	true
done
}

function pdfjoin {
while true; do
	if ! PFAD=$(/usr/bin/$DIALOG --title "Ordner mit den zusammenzufügenden PDF-Dateien wählen" --getexistingdirectory "$USERPFAD"); then
		return
	fi
	ANZAHL=$(ls "$PFAD"/*.pdf | wc -l)
	if [ $ANZAHL == 1 ]; then
		/usr/bin/$DIALOG --error "In dem Ordner befindet sich nur eine PDF-Datei!"
		continue
	elif [ $ANZAHL == 0 ]; then
		/usr/bin/$DIALOG --error "In dem Ordner befinden sich keine PDF-Dateien!"
		continue
	fi
	if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
		continue
	fi
	break
done
cd "$PFAD"
pdftk *.pdf cat output "$SPEICHERN"
exit
}

function pdfburst {
while true; do
	if ! DATEI=$(/usr/bin/$DIALOG --title "Aufzuteilende PDF-Datei auswählen" --getopenfilename "$USERPFAD"); then
		return
	fi
	if [ $(pdfinfo "$DATEI" | grep Pages | head -6 | tail -1 | awk '{print $2}') == 1 ]; then
		/usr/bin/$DIALOG --error "Die ausgewählte PDF-Datei hat nur eine Seite, aufteilen ist nicht möglich!"
		continue
	fi
	if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die einzelnen PDF-Dateien erstellt werden?" --getexistingdirectory "$USERPFAD"); then
		continue
	fi
	break
done
cd "$SPEICHERN"
pdftk "$DATEI" burst
rm doc_data.txt
exit
}

function pdfturn {
while true; do
	if ! DATEI=$(/usr/bin/$DIALOG --title "Zu drehende PDF-Datei auswählen" --getopenfilename "$USERPFAD" *.pdf); then
		return
	fi
	if ! DREHEN=$(/usr/bin/$DIALOG --title "PDF drehen" --menu "Wie soll gedreht werden?" A1L "90° Linksdrehung" A1R "90° Rechtsdrehung" A1D "180° Drehung"); then
		continue
	fi
	if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
		continue
	fi
	pdftk A="$DATEI" cat $DREHEN output "$SPEICHERN"
	if [ $? -eq 1 ]; then
		/usr/bin/$DIALOG --error "Start- und Zieldatei sind identisch!\n Bitte unter einem anderen Namen speichern."
		continue;
	fi
	break
done
exit
}

function pdfdecrypt {
while true; do
	if ! DATEI=$(/usr/bin/$DIALOG --title "Passwortgeschütze PDF auswählen - Passwort muss bekannt sein!" --getopenfilename "$USERPFAD" *.pdf); then
		return
	fi
	if ! PASSWORT=$(/usr/bin/$DIALOG --title "Passwort entfernen" --password "Bitte geben Sie das Passwort der PDF-Datei ein:"); then
		continue
	fi
	if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
		continue
	fi
	pdftk "$DATEI" input_pw "$PASSWORT" output "$SPEICHERN"
	if [ $? -eq 1 ]; then
		/usr/bin/$DIALOG --error "Start- und Zieldatei sind identisch!\n Bitte unter einem anderen Namen speichern."
		continue
	fi
	break
done
exit
}

function pdfcrypt {
while true; do
	if ! DATEI=$(/usr/bin/$DIALOG --title "PDF auswählen, die verschlüsselt  werden soll" --getopenfilename "$USERPFAD" *.pdf); then
		return
	fi
	if ! PASSWORT=$(/usr/bin/$DIALOG --title "Besitzer-Passwort hinzufügen" --password "Bitte geben Sie das gewünschte Passwort ein:"); then
		continue
	fi
	USERPASSWORT=""
	if /usr/bin/$DIALOG --title "Passwortschutz" --yesno "Soll ein Passwort zum öffnen der PDF-Datei erforderlich sein?"; then
		if ! PASSWORT2=$(/usr/bin/$DIALOG --title "Benutzer-Passwort hinzufügen" --password "Bitte geben Sie das gewünschte Passwort ein:"); then
			continue
		fi
	USERPASSWORT="user_pw $PASSWORT2"
	fi
	if ! OPTIONEN=$(/usr/bin/$DIALOG --title "PDF Optionen" --separate-output --checklist "Bitte auswählen, wenn was in der PDF-Datei erlaubt sein soll:" "allow Printing" "Drucken" off "allow ModifyContents" "Inhalt verändern" off "allow CopyContents" "Inhalt kopieren" off "allow ModifyAnnotations" "Kommentare hinzufügen" off); then
		continue
	fi
	if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Speichern unter" --getsavefilename "$USERPFAD" *.pdf); then
		continue
	fi
	pdftk "$DATEI" output "$SPEICHERN" owner_pw $PASSWORT $USERPASSWORT $OPTIONEN
	if [ $? -eq 1 ]; then
	/usr/bin/$DIALOG --error "Start- und Zieldatei sind identisch!\n Bitte unter einem anderen Namen speichern."
		continue
	fi
	break
done
exit
}

function pdfimages {
while true; do
	if ! DATEI=$(/usr/bin/$DIALOG --title "PDF-Datei auswählen, aus welcher die Bilder extrahiert werden sollen" --getopenfilename "$USERPFAD" *.pdf); then
		return
	fi
	if ! SPEICHERN=$(/usr/bin/$DIALOG --title "Wo sollen die Bilder gespeichert werden?" --getexistingdirectory "$USERPFAD"); then
		continue
	fi
	break
done
pdfimages "$DATEI" "$SPEICHERN"/
exit
}

hauptprogramm

exit 0
Antworten |