Page 1 of 2

Shell-Skript-Programmierung

Posted: 25. Oct 2008 17:54
by Felix2000
Ich habe mir dazu das Buch "Einführung in die Bash-Shell" vom O´Reilly Verlag besorgt. Hier wird ein Codebeispiel im Buch durchgenommen, dass ich auch anhand der Erklärung im Buch nicht ganz verstehe.

Hier der Code:

Code: Select all

pushd()
{
   dirname=$1
   DIR_STACK="$dirname ${DIR_STACK:-$PWD' '}"
   cd ${dirname:?"fehlender Verzeichnisname."}
   echo "$DIR_STACK"
} 
Ich verstehe hier nicht ganz diese Zeile: DIR_STACK="$dirname ${DIR_STACK:-$PWD' '}"

Wie genau arbeiten hier $dirname und ${DIR_STACK:-$PWD' '} zusammen? Ich habe herausbekommen, dass DIR_STACK eine Umgebungsvariable ist. Vielleicht könnt ihr mir die Codezeile erklären?

Vielen Dank

Posted: 25. Oct 2008 21:45
by Janka
dirname, DIR_STACK und PWD sind in diesem Skript Umgebungsvariablen. PWD ist eine von der Shell automatisch auf das aktuelle Verzeichnis gesetzte Variable.
${DIR_STACK:-$PWD' '} gibt den Inhalt der Variablen DIR_STACK zurück, falls diese gesetzt ist, sonst das Ergebnis des Ausdrucks $PWD' '.

Die bash-Manpage ist hier sehr hilfreich, da sind diese Auswerte-Konstrukte beschrieben.

Janka

Posted: 25. Oct 2008 22:13
by Felix2000
Hallo Janka !

Danke für Dein Post! Am besten ich formuliere die Frage nochmal etwas um: Warum stehen $dirname und ${DIR_STACK:-$PWD' '} direkt hintereinander? Ist ${DIR_STACK:-$PWD' '} etwas eine Option für $dirname ? Ich verstehe nicht ganz wie das zu interpretieren ist?

Wie der Ausdruck ${DIR_STACK:-$PWD' '} innerhalb eines Skriptes ausgewertet wird, ist sehr gut im oreilly Buch beschrieben, aber leider nicht der gesamte Ausdruck "$dirname und ${DIR_STACK:-$PWD' '} "

Grüße
Felix

Posted: 25. Oct 2008 23:39
by Janka
$dirname ist kein Befehl, sondern einfach der Inhalt der Variable "dirname". Schreibt man in der Shell Quotes ("), so wird alles in den Quotes als ein String interpretiert, Referenzen werden ausgewertet. Außer den Quotes gibt es auch noch die Ticks ('), diese begrenzen auch Strings, allerdings werden keine Referenzen dazwischen ausgewertet.

Janka

Posted: 26. Oct 2008 19:22
by Felix2000
Ok danke Janka !

Mal was anderes: Gibt es eigentlich irgendwo eine brauchbare Internetseite, auf der viele Befehle inkl. der gültigen Reihenfolge ihrer Argumente aufgelistet und erklärt werden? Irgendwie finde ich es ziemlich undurchsichtig, mir die Grundlagen der Shell-Programmierung anzueignen.

Das folgende Kommando z.B.

Code: Select all

find . -perm 600 -exec chmod g+rw {} \;
Hier steht ja die {} z.B. für die Liste, die find mir zurückgibt. Glaube ich zumindest. Wie gesagt solche Dinge würde ich gerne irgendwo nachlesen. Gibt es so etwas wie eine große Doku, die vielleicht ähnlich wie eine Beschreibung von diversen Klassen und Methoden bei Java aufgebaut ist?

Posted: 26. Oct 2008 21:17
by Janka
Es gibt für fast jeden Befehl eine Handbuchseite. Diese erhältst du mit "man Befehl" oder im Konqueror über #Befehl. Oft gibt es auch eine Infoseite, diese erhältst du mit "info Befehl" oder im Konqueror über "##Befehl".

Außerdem kannst du Manpages im Internet lesen. Z.B. bei http://www.freebsd.org/cgi/man.cgi

Janka

Posted: 27. Oct 2008 8:54
by Felix2000
Super vielen Dank !!

Posted: 10. Nov 2008 21:36
by Felix2000
Hallo !

Hab nochmal eine Frage, wann genau muss ich in If, For oder While Schleifen mit den eckigen Klammern arbeiten? Manchmal finde ich Beispiele, wo eckige Klammern gesetzt sind und manchmal welche, wo darauf verzichtet wird. :(

Posted: 11. Nov 2008 6:56
by Janka
Die eckigen Klammern entsprechen dem in der Shell eingbauten Befehl "test" -- übrigens ein guter Grund, eigene Programme niemals "test" zu nennen.

Wenn $a gleich $b dann tu c kann man also z.B wie folgt schreiben:

Code: Select all

if test "$a" = "$b"
then
  c
fi

if [ "$a" = "$b" ]
then
  c
fi

[ "$a" = "$b" ] && c
etc. etc.

Der test-Befehl macht etwas mit seinen Argumenten und liefert "0" oder "nicht 0" zurück. "if" seinerseits vergleicht nur auf "0" oder "nicht 0". Genauso macht das "&&".

Du kannst statt test auch jeden anderen Befehl nehmen, der "0" oder "nicht 0" zurückliefert. Üblicherweise liefern Befehle "0" zurück, wenn sie erfolgreich beendet werden konnten. Oft gesehenes Beispiel

Code: Select all

$ ./configure && make && sudo make install
Also ./configure ausführen, falls dies geklappt hat, make ausführen, falls dies geklappt hat sudo make install ausführen.

Janka

Posted: 11. Nov 2008 11:11
by Felix2000
Vielen Dank ! Das muss man erstmal wissen ! Wie genau verhält sich denn der "test" wenn ich versuche mit Negationen zu arbeiten? Also bspw.

Code: Select all

if ! [ $a && $b ] then

blabla
oder so

Code: Select all

if  [ ! $a && $b ] then

blabla
Muss die then-Anweisung eigentlich immer auf der Höhe der If Anweisung stehen?

Grüße
Felix

Posted: 11. Nov 2008 15:12
by Janka
Es geht beides, da "!" ebenfalls ein Kommando ist. Es wertet das nachfolgende Kommando aus und macht aus "0" "nicht 0", und umgekehrt. Im test-Kommando ist ! wird als Negationsoperator ausgewertet.

Code: Select all

$ ! true ; echo $?
$ ! false ; echo $?
then kann auch auf einer eigenen Zeile stehen. Probier es doch einfach aus!

Janka

Posted: 07. Dec 2008 16:34
by Felix2000
Hallo Janka !

Ich muss dich nochmal etwas fragen. Ich habe in vielen Shell Skripten gesehen, dass Variablen oft so geschrieben werden, bspw. in Testbefehlen, IF Anweisungen, while Schleifen usw.

"$@" oder so "$dirname" oder so "$2"

Hier nochmal zwei weitere Beispiele:

Code: Select all

if [ -d "$2" ]
then

blabla

fi
oder

Code: Select all

if [ -r "$1" ]
then

blabla

fi
Warum maskiert man manche Variablen so? Was genau habe ich davon für einen Nutzen? Ich gehe davon aus, dass es sich um Variablen in irgendwelchen Shellskripten handelt.

Viele Grüße
Felix

Posted: 07. Dec 2008 19:30
by Janka
Sinnvoll ist das nur beim Vergleichen zweier Werte. Wenn die Variable den Leerstring enthält oder einfach nicht definiert ist meckert "test" nämlich sonst rum, dass es nur einen einzigen Parameter hätte.

$ A=
$ [ $A = X ]
bash: [: =: unary operator expected

Janka

Posted: 07. Dec 2008 19:52
by Felix2000
Ok, aber es ist auch nicht grundsätzlich falsch, wenn ich mit maskierten Variablen arbeite!? Mal davon abgesehen, ob es sinnvoll ist oder nicht. Tut mir leid, dein Beispiel verstehe ich nicht ganz :?

Posted: 07. Dec 2008 21:13
by Janka
Wenn du grundsätzlich "" drummachst, passiert bei "test" zumindest nichts Schlimmes. Es zeigt aber dem Leser des Skriptes, dass der Ersteller keine Ahnung hat, was er tut und warum.

Wenn du das Beispiel nicht verstehst, probier das Gegenbeispiel:

$ A=
$ [ "$A" = X ]

Hier gibt es nämlich *keine* Fehlermeldung.

Janka