bash if und else (gelöst)

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

bash if und else (gelöst)

Beitrag von guennid » 01.04.2011 21:05:43

Was macht man denn, wenn man in einem bash-shell-script im else-Zweig eines ifs zwei ifs braucht? Geht das so:

Code: Alles auswählen

if [bedingung] then
  kommando(s)
 else
  if [bedinung] then
     kommando(s)
  if [bedinung] then
     kommando(s)
fi  
oder so:

Code: Alles auswählen

if [bedingung] then
  kommando(s)
 else
  if [bedinung] then
     kommando(s)
  fi
  if [bedinung] then
     kommando(s)
  fi
fi  
oder noch anders?

Grüße, Günther
Zuletzt geändert von guennid am 03.04.2011 07:48:29, insgesamt 1-mal geändert.

Benutzeravatar
Meillo
Moderator
Beiträge: 9247
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash if und else

Beitrag von Meillo » 01.04.2011 21:16:49

Zweiteres.

Wobei Strichpunkte vor den `then's fehlen.
Use ed once in a while!

guennid

Re: bash if und else

Beitrag von guennid » 01.04.2011 21:30:02

Wobei Strichpunkte vor den `then's fehlen.
mit Strichpunkten meinst du sowas: ; (Semikolon)? Das krieg ich schon hin. Ich müsste wissen, was mit fi ist.
Ich kann's auch mal auf deutsch versuchen

Code: Alles auswählen

wenn, dann
    mach1
    mach2
    mach....
  sonst
     wenn dann 
       mach1
       mach2
       mach....
    wenn-Ende
    wenn dann
       mach
       mach2
       mach....
    wenn-ende
wenn-sonst-ende
So würde das in pascal funktionieren, begin/end schenk ich mir hier, das gibt's in der bash wohl sowieso nicht.

guennid

Re: bash if und else

Beitrag von guennid » 01.04.2011 21:44:23

Hey, ich habe was gefunden:

Code: Alles auswählen

if [ -r $1 ]
   8: then
   9:   # Name der Ausgabedatei
  10:   out="$1.html"
  11: 
  12:   # Lege den Anfang der HTML-Datei an
  13:   echo -e "<html>\n<head>\n<title>$1</title>\n</head>\n<body>\n" > $out
  14:   echo -e "<h1 align='center'>Listing: $1</h1>\n<pre>" >> $out
  15: 
  16:   # Datei durchnummerieren und spitze Klammern behandeln
  17:   sed "s/</\</g" $1 | sed "s/>/\>/g" \
  18:     | expand | nl -w 4 -b a -s ": " >> $out
  19: 
  20:   # Ende der HTML-Datei
  21:   echo -e "</pre>\n</body>\n</html>\n" >> $out
  22: else
  23:   # Existiert die Datei oder ist sie nur nicht lesbar? 
  24:   if [ -e $1 ]
  25:   then
  26:     # Fehlerausgabe auf Fehlerkanal
  27:     echo "Die Datei $1 ist nicht lesbar." > /dev/stderr
  28:     exit 1      # Beenden mit Fehlercode        
  29:   else
  30:     # Fehlerausgabe auf Fehlerkanal
  31:     echo "Die Datei $1 existiert nicht." > /dev/stderr
  32:     exit 2      # Beenden mit Fehlercode
  33:   fi
  34: fi
Wenn das Beispiel korrekt ist, dann gelten wohl tatsächlich auch in der bash mitunter die Regeln der Logik :mrgreen: , will sagen: jedes if im else-Zweig muss mit fi beendet werden und danach das übergeordnete if. Kann mir das jemand bestätigen?

Benutzeravatar
Meillo
Moderator
Beiträge: 9247
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash if und else

Beitrag von Meillo » 01.04.2011 21:53:39

guennid hat geschrieben:Kann mir das jemand bestätigen?
Hatte ich dir doch schon oben so gesagt. :roll:


Da ich sehe, dass du aus der Pascal-Welt kommst: Sehe `then' als `begin' und `fi' als `end' an.
Use ed once in a while!

guennid

Re: bash if und else

Beitrag von guennid » 01.04.2011 22:08:47

'Tschuldigung, erste Zeile überlesen: Mea culpa, mea culpa, mea maxima culpa! :hail:

Benutzeravatar
Meillo
Moderator
Beiträge: 9247
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash if und else

Beitrag von Meillo » 02.04.2011 00:55:06

guennid hat geschrieben:'Tschuldigung, erste Zeile überlesen: Mea culpa, mea culpa, mea maxima culpa! :hail:
Nur nicht uebertreiben. Das passiert jedem ab und zu. ;-)
Use ed once in a while!

guennid

Re: bash if und else

Beitrag von guennid » 02.04.2011 09:34:33

Code: Alles auswählen

#!/bin/sh
# 
stromquelle=$(acpi -a)
akku=$(acpi -b)

if [ $akku="" ]; then
   agb="n.v."
   echo "<span foreground='yellow'><small>"$agb"</small></span>"
  else
   if [ "$stromquelle" = "Adapter 0: on-line" ]; then
     echo "<span foreground='blue'><small>""B:"$(acpi -b | cut -d, -f2)"</small></span>"
   fi
   if [ "$stromquelle" = "Adapter 0: off-line" ]; then
     echo "<span foreground='red'><small>""B:"$(acpi -b | cut -d, -f2)"</small></span>"
   fi
fi
Dieses script, tut, soweit ich sehe, was es soll.
Möchte mir mal jemand verraten, warum ich in

Code: Alles auswählen

if [ $akku="" ]; then
die Gänsefüßchen um: $akku und die Leerzeichen um: = weglassen darf, in

Code: Alles auswählen

if [ "$stromquelle" = "Adapter 0: on-line" ]; then
und

Code: Alles auswählen

if [ "$stromquelle" = "Adapter 0: off-line" ]; then
jedoch nicht?

Grüße, Günther

Benutzeravatar
Meillo
Moderator
Beiträge: 9247
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash if und else

Beitrag von Meillo » 02.04.2011 10:56:13

guennid hat geschrieben: Möchte mir mal jemand verraten, warum ich in

Code: Alles auswählen

if [ $akku="" ]; then
die Gänsefüßchen um: $akku und die Leerzeichen um: = weglassen darf, in

Code: Alles auswählen

if [ "$stromquelle" = "Adapter 0: on-line" ]; then
und

Code: Alles auswählen

if [ "$stromquelle" = "Adapter 0: off-line" ]; then
jedoch nicht?
Weil im zweiteren Leerzeichen enthalten sind.

Logisch ist das einmal:

Code: Alles auswählen

if [ string = string ] ; then
und im anderen Fall:

Code: Alles auswählen

if [ string string = string string ] ; then
Das ist aber keine valide Syntax fuer test(1). Deshalb geht das so nicht.

Variablen in der Shell sollte man so gut wie immer (ausser man weiss was man tut) in doppelte Anfuehrungszeichen stecken um Ueberraschungen und Sicherheitsprobleme zu umgehen.

Was z.B. wenn $akku leer ist? Dann kommt das an:

Code: Alles auswählen

if [ = "" ] ; then
... eben auch keine valide test(1)-Syntax.


Du darfst nicht vergessen, dass die Shell staerker textorientiert ist als ``richtige'' Programmiersprachen. Die Inhalte von Variablen koennen logische Spracheinheiten entstehen oder verschwinden lassen.
Use ed once in a while!

guennid

Re: bash if und else

Beitrag von guennid » 02.04.2011 15:51:02

Was z.B. wenn $akku leer ist?
Das sollte sich doch durch Initialisierung der Variablen akku und stromquelle regeln lassen, z.B.

Code: Alles auswählen

stromquelle=""
akku=""
stromquelle=$(acpi -a)
akku=$(acpi -b)
oder gibt's da auch wieder Hintertüren, Besonderheiten, etc.?

Oder meinst du einen leeren Akku. Der dürfte mangels Strom gar nicht ausgebbar sein. :wink:

Habe ich recht verstanden, dass du nur auf die Gänsefüßchen eingegangen bist? Was ist mit den Leerzeichen ums Gleichheitszeichen herum? bei "$stromquelle" brauch ich sie, bei $akku sind sie verboten. 8O

Grüße, Günther

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: bash if und else

Beitrag von newdeb » 02.04.2011 18:00:09

Eine Initialisierung der Variablen mit dem Leerstring nützt nichts,
Du musst die Variable in [ ] (bzw. test-Kommando) quotieren (doppelte Anführungszeichen, damit die Shell den Wert substituiert).
Du kannst auch die Doppelklammern [[ ]] verwenden, die sind weniger zickig, was leere Variablen angeht.

Code: Alles auswählen

var1=foo
var2=""
[ $var1 = $var2 ]
bash: [: foo: unary operator expected

[ "$var1" = "$var2" ]
[[ $var1 = $var2 ]]
Um den Vergleichsoperator sind grundsätzlich Leerzeichen notwendig.
Das Test-Konstrukt [ $akku="" ] ist zwar zulässig, hat aber nicht die gewünschte Bedeutung.
Hier wird der Inhalt in den Klammern als einzelne Zeichenkette aufgefasst und getestet, ob diese Zeichenkette nicht-leer ist.
(nach Substitution der Variablen akku durch die Shell).
Es entspricht also einem Test mit der Option -n:

Code: Alles auswählen

[ -n $akku="" ]

guennid

Re: bash if und else

Beitrag von guennid » 02.04.2011 19:51:29

Mit

Code: Alles auswählen

akku=$(acpi -b)
will ich die Zeichenkette, die das Kommando acpi -b ausgibt, der Variablen akku zuweisen. Ist das erstmal richtig?

Wenn das Notebook ohne Akku läuft, gibt acpi -b nichts aus. Das wollte ich prüfen mit:

Code: Alles auswählen

if [ $akku="" ]; then
. Das ist, wenn ich dich richtig verstehe, Unsinn. Kann man den leeren Inhalt einer Variablen nicht oder nur umständlich mit dem Gleichheitszeichen prüfen? Aus Ditchen: Shell-Script Programierung S.91 habe ich mir jetzt das hier für diese Prüfung abgeleitet:

Code: Alles auswählen

if [ -z "$akku" ]; then
. Ist das jetzt korrekt?

Es wäre schön, wenn wir bei meinen Bezeichnern bleiben könnten, sonst muss ich wieder nachfragen, was z.B. foo/FOO eigentlich bedeutet. Mir ist zwar schon aufgefallen, dass das von den Eingeweihten häufig benutzt wird, aber eine Erklärung ist mir dabei noch nicht untergekommen, wird wohl als selbstverständlich vorausgesetzt.

Grüße, Günther

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: bash if und else

Beitrag von newdeb » 02.04.2011 20:29:45

Mit

Code: Alles auswählen

akku=$(acpi -b)
will ich die Zeichenkette, die das Kommando acpi -b ausgibt, der Variablen akku zuweisen. Ist das erstmal richtig?
Ja!
Aus Ditchen: Shell-Script Programierung S.91 habe ich mir jetzt das hier für diese Prüfung abgeleitet:

Code: Alles auswählen

if [ -z "$akku" ]; then
. Ist das jetzt korrekt?
Ja!
Es wäre schön, wenn wir bei meinen Bezeichnern bleiben könnten, sonst muss ich wieder nachfragen, was z.B. foo/FOO eigentlich bedeutet. Mir ist zwar schon aufgefallen, dass das von den Eingeweihten häufig benutzt wird, aber eine Erklärung ist mir dabei noch nicht untergekommen, wird wohl als selbstverständlich vorausgesetzt.
"foo" ist in diesem Beispiel einfach ein Platzhalter für einen beliebigen Variableninhalt, "xyz", "bla", "blub" wären genauso gut (oder schlecht :wink: )
Zur Geschichte von foo/bar siehe http://de.wikipedia.org/wiki/Fubar

Benutzeravatar
Meillo
Moderator
Beiträge: 9247
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash if und else

Beitrag von Meillo » 02.04.2011 21:00:24

guennid hat geschrieben: Wenn das Notebook ohne Akku läuft, gibt acpi -b nichts aus. Das wollte ich prüfen mit:

Code: Alles auswählen

if [ $akku="" ]; then
. Das ist, wenn ich dich richtig verstehe, Unsinn.
Nur in sofern dass es *so* unsinnig ist. Dagegen ist es so korrekt:

Code: Alles auswählen

if [ "$akku" = "" ] ; then
(Das ist synonym zu der Version mit -z.)
Use ed once in a while!

guennid

Re: bash if und else

Beitrag von guennid » 02.04.2011 21:04:26

Danke sehr!
Die Erklärung in wikipedia versteh ich aber eher so, dass foo ein allgemeiner Variablenbezeichner, nicht der Inhalt/Wert einer x-beliebigen Variablen ist.

Wie steht's mit dieser Frage:
Kann man den leeren Inhalt einer Variablen nicht oder nur umständlich mit dem Gleichheitszeichen prüfen?
Das hat dann ja wohl meillo beantwortet! Ebenso Danke!

Günther

Benutzeravatar
Meillo
Moderator
Beiträge: 9247
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash if und else

Beitrag von Meillo » 02.04.2011 22:20:15

guennid hat geschrieben: Die Erklärung in wikipedia versteh ich aber eher so, dass foo ein allgemeiner Variablenbezeichner, nicht der Inhalt/Wert einer x-beliebigen Variablen ist.
``foo'' nimmt man einfach immer wenn man nicht weiss wie man etwas nennen soll. Entscheidend daran ist nur, dass jeder weiss, dass ``foo'' ein Platzhalter fuer irgendwas ist.
Use ed once in a while!

Antworten