Page 1 of 1

Shellprogrammierung

Posted: 2006-04-01 17:26
by joern
Moin,

probiere mic gerade ein wenig in Shellprogrammierung und hätte
da mal eine kleine Frage:

Ich lese also ein Verzeichnis über die Standardeingabe ein.

read verzeichnis

Jetzt würde ich gern wissen, ob in der Variablen mindestens ein Slash enthalten ist. Wie bewerkstellige ich das ?


Danke
Jörn

Re: Shellprogrammierung

Posted: 2006-04-01 17:38
by Joe User
man grep
man wc

Re: Shellprogrammierung

Posted: 2006-04-01 17:38
by thorsten
Schreib mal was du damit bezwecken möchtest. vllt. ist auch folgendes hilfreich für dich:
info coreutils dirname
info coreutils basename

Ansonsten schau dir test -f oder test -d an - je nachdem was du machen möchtest.

Re: Shellprogrammierung

Posted: 2006-04-01 18:34
by joern
Ja, entweder gibt der User den absoluten Pfad an oder er gibt einfach nur den Verzeichnisnamen an zu dem er wechseln möchte.
Das zum Hintergrund.

Nun habe ich Folgendes:

Wenn diese Bedingung erfüllt ist, ist der absolute Pfad angegeben worden

if test `echo $verzeichnis | grep "/" | wc -m` != 0

Wie ihr seht habe ich einfach alle Befehle, die ihr vorschlugt, verarbeitet :-)

Danke

Jörn

Re: Shellprogrammierung

Posted: 2006-04-01 18:44
by Joe User
Input vertraut man niemals blind:

Code: Select all

./script.sh cd/rel/path

Re: Shellprogrammierung

Posted: 2006-04-01 18:56
by isotopp
Joern wrote:Jetzt würde ich gern wissen, ob in der Variablen mindestens ein Slash enthalten ist. Wie bewerkstellige ich das ?
Shells arbeiten zeilen- und wortweise. Wenn Du zeichenweise arbeiten möchtest ist das ein sicherer Indikator für "Ich hätte perl verwenden sollen."

Dennoch ist Dein Problem in Shell lösbar. Sei

kris@linux:~> strslashed="a/b"
kris@linux:~> strunslashed="abc"

Lösung a:

kris@linux:~> case "$strslashed" in
> */*) echo "slashed";;
> *) echo "unslashed";;
> esac
slashed
kris@linux:~> case "$strunslashed" in
> */*) echo "slashed";;
> *) echo "unslashed";;
> esac
unslashed

Diese Lösung verändert keine systemkritischen Variablen und setzt nur interne Shellkommandos ein. Sie ist die empfohlene Lösung.

Lösung b:

shell> OFS="$IFS"
shell> IFS=/
shell> set -- $slashed
shell> num=$#
shell> IFS="$OFS"
shell> echo $num
2

Mithin kannst Du hier

if [ "$num" -gt 1 ]
then
echo "slashed"
else
echo "unslashed"
fi

Diese Lösung verändert die systemkritische Variable IFS, aber nur temporär. Sie überschreibt $@, $* und $#. Sie bestimmt aber in einem arbeitsgang und unter ausschließlicher Verwendung von internen Kommandos die absolute Anzahl der Slashes ($num - 1).

Lösung c:

kris@linux:~> testname=$(basename $slashed)
kris@linux:~> if [ "$testname" != "$slashed" ]
> then
> echo "slashed"
> else
> echo "unslashed"
> fi
slashed

Diese Lösung verwendet das externe Kommando basename, ist also langsam.

Es existieren noch weitere Lösungen, aber diese sind alle schlechter als die oben gezeigten Lösungen.

Re: Shellprogrammierung

Posted: 2006-04-01 19:00
by isotopp
Joern wrote:

Code: Select all

if test `echo $verzeichnis | grep "/" | wc -m` != 0
Deinen Ausführungen entnehme ich, daß $verzeichnis eine Benutzereingabe enthält. Die Syntax `...` (sh, bash) oder $(...) (bash) führt eine Kommandosubstition durch, d.h. der Teil in dem Operator wird ausgeführt und durch seine Ausgabe ersetzt.

Du erlaubst hier also dem Benutzer, eine beliebige Eingabe auszuführen. Stelle Dir vor, $verzeichnis sei "bla; rm -rf $HOME; echo lall" und setze diesen Inhalt in Dein Kommando oben ein. Was passiert?

Der Mechanismus `` bzw $() existiert auch in anderen Sprachen, etwa PHP, Perl und vielen anderen. Er heißt dort traditionell "eval". Benutzereingaben in eval's zu tun ist eine gute Methode sein Programm sofort zu einem größeren Sicherheitsleck zu machen.

Verwende eine beliebige Lösung, die ohne eval auskommt.

Re: Shellprogrammierung

Posted: 2006-04-01 19:43
by joern
Hallo Isotopp,

herzlichen Dank für deine Ausführungen. Ich muss allerdings ein Shell Script vewenden, Perl kommt leider nicht in Frage.

Deine erste Ausführung ist Spitze. Die werde ich nehmen.


Viele Grüße
Jörn