(BASH) Mehrere Bedingungen für if? Verzeichnis des Skripts?

- programmiertechnik
Hallo an alle,
heute habe ich mir vorgenommen, wieder etwas am EMFF 0.5 zu arbeiten. Ich schreibe gerade ein Shell-Skript zum Erstellen von Skins, und bin bis jetzt auf zwei Probleme gestoßen.
Mit dem folgenden Code kann ich testen, ob "../skins/$1/" ein gültiges Verzeichnis ist:
if [ -d "../skins/$1/" ]
then
echo "directory is valid!"
else
echo "usage: $0 <name of skin>"
fi
Nun möchte ich aber mehrere Bedingungen angeben, ausgesprochen so:
Wenn "../skins/$1/" ein gültiges Verzeichnis ist UND $1 nicht gleich "" ist UND "../skins/$1/$inputmtasc" eine gültige Datei ist DANN ...
Einzeln bekomme ich die Abfragen hin, aber die Verbindung mit UND bereitet mir Probleme.
Das zweite Problem:
Ich rufe das Skript normalerweise mit "./createskin.sh" auf. Es wäre aber möglich, dass jemand das Skript mit "bin/createskin.sh" aufruft.
Da das Ganze später in einem Archiv verteilt wird bin ich auf relative Pfade angewiesen.
Gut wäre es also, wenn ich zu Beginn die Möglichkeit hätte, das Verzeichnis herauszufinden, in dem das Skript läuft.
Wenn das Skript also unter /home/benutzer/emff0.5dev/bin/createskin.sh aufgerufen wird, soll es auf jeden Fall in /home/benutzer/emff0.5dev/bin/ arbeiten, und _nirgendwo sonst_.
Wenn dies nicht möglich ist, gäbe es dann eine Möglichkeit, wenigstens diesen Fall abzufangen und das Skript zu beenden?
Grüße und vielen Dank im Voraus
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc.
Nun möchte ich aber mehrere Bedingungen angeben, ausgesprochen so:
Wenn "../skins/$1/" ein gültiges Verzeichnis ist UND $1 nicht gleich "" ist UND "../skins/$1/$inputmtasc" eine gültige Datei ist DANN ...
Einzeln bekomme ich die Abfragen hin, aber die Verbindung mit UND bereitet mir Probleme.
AFAIK kannst du hier nur verschachteln:
if [ Erste Bedingung ];then
if [ Zweite Bedingung ];then
alles_ok;
fi
fi
Wenn das Skript also unter /home/benutzer/emff0.5dev/bin/createskin.sh aufgerufen wird, soll es auf jeden Fall in /home/benutzer/emff0.5dev/bin/ arbeiten, und _nirgendwo sonst_.
Also jeweils ausgehend von „.“? Oder wo genau liegt hier das Problem?
Kann man sich das Script einmal anschauen?
Einen schönen Mittwoch noch.
Gruß, Mathias
Hallo nochmal.
Einzeln bekomme ich die Abfragen hin, aber die Verbindung mit UND bereitet mir Probleme.
AFAIK kannst du hier nur verschachteln:
Offenbar nicht, siehe „compound operators“ auf dieser Seite.
Einen schönen Mittwoch noch.
Gruß, Mathias
Hallo Mathias,
Offenbar nicht, siehe „compound operators“ auf dieser Seite.
Doch, ich hab's jetzt hinbekommen! :-)
Das Skript sieht derzeit so aus:
<code file="createskin.sh">
#!/bin/bash
binarymtasc="mtasc"
classpath="/usr/local/bin/std/"
binaryswfmill="swfmill"
mtascflags="-version 6 -strict -wimp -header 600:400:31"
tempcompilation="compilation.temp.swf"
inputmtasc="Skin.as"
inputswfmill="swfmill.xml"
cd ../temp/
if [ "$1" != "" ] && [ -d "../skins/$1/" ] && [ -f "../skins/$1/$inputmtasc" ] && [ -f "../skins/$1/$inputswfmill" ]
then
# seems to be ok
else
echo "usage: $0 <name of skin>"
exit 1
fi
cp -rf ../skins/$1/* ./
$binarymtasc -cp $classpath -cp ../code/ $mtascflags $inputmtasc -swf $tempcompilation
$binaryswfmill simple $inputswfmill "../skins/$1.swf"
exit 0
</code>
Derzeit ist die letzte Zeile - das Löschen der temporären Dateien - noch auskommentiert, da der Befehl sich, wenn er im falschen Ordner aufgerufen wird, ziemlich gravierend auswirken könnte. Genau dazu brauche ich nämlich eine Anweisung, dass das Skript auch garantiert im richtigen Ordner aufgerufen wird.
Hmm, außerdem habe ich noch ein kleines Problem: Im temp-Ordner gibt es eine Datei "IMPORTANT", die natürlich nicht gelöscht werden soll.
Gibt es dafür einen Shell-Ausdruck, damit diese Datei nicht mit gelöscht wird? Ich tippe auf einen regulären Ausdruck...
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo nochmals,
eine kleine Korrektur: Die Bash scheint den folgenden Code nicht zu mögen:
if [ "$1" != "" ] && [ -d "../skins/$1/" ] && [ -f "../skins/$1/$inputmtasc" ] && [ -f "../skins/$1/$inputswfmill" ]
then
# seems to be ok
else
echo "usage: $0 <name of skin>"
exit 1
fi
habe ihn nun durch
if [ "$1" != "" ] && [ -d "../skins/$1/" ] && [ -f "../skins/$1/$inputmtasc" ] && [ -f "../skins/$1/$inputswfmill" ]
then
echo "ok, will create skin '$1'"
else
echo "usage: $0 <name of skin>"
exit 1
fi
ersetzt, da die Bash witzigerweise nach dem "then" einen Befehl erwartet, ich ihr aber keinen geben wollte. Auch ein Semikolon mag sie an dieser Stelle nicht, hmm...
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc.
change to temp directory - this is the only directory where we will work
cd ../temp/
Warum arbeitest du nicht in einem Unterverzeichnis unter /tmp?
Genau dazu brauche ich nämlich eine Anweisung, dass das Skript auch garantiert im richtigen Ordner aufgerufen wird.
Ich rate dir wirklich, ein Arbeitsverzeichnis festzulegen in welchem dann ungeachtet des Systemes gearbeitet wird.
Einen schönen Mittwoch noch.
Gruß, Mathias
Hallo Mathias,
change to temp directory - this is the only directory where we will work
cd ../temp/
Warum arbeitest du nicht in einem Unterverzeichnis unter /tmp?
Gute Frage. ;-)
Genau dazu brauche ich nämlich eine Anweisung, dass das Skript auch garantiert im richtigen Ordner aufgerufen wird.
Ich rate dir wirklich, ein Arbeitsverzeichnis festzulegen in welchem dann ungeachtet des Systemes gearbeitet wird.
Dazu hatte ich ja meinen eigenen temp-Ordner angelegt. Nur hier soll das Skript später arbeiten. Ist das denn nicht irgendwie mit einem Shell-Kommando realisierbar?
Ich möchte es später so haben, dass die Datei möglichst überall aufgerufen werden kann. Unter UNIX geht es, unter Windows dank Cygwin auch.
Wie sieht es mit Mac aus? Da ist ja auch ein Unix - aber haben die auch ein /tmp-Verzeichnis?
Dann könnte ich mir z. B. unter /tmp/emff ein Arbeitsverzeichnis anlegen.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc.
Genau dazu brauche ich nämlich eine Anweisung, dass das Skript auch garantiert im richtigen Ordner aufgerufen wird.
Ich rate dir wirklich, ein Arbeitsverzeichnis festzulegen in welchem dann ungeachtet des Systemes gearbeitet wird.
Dazu hatte ich ja meinen eigenen temp-Ordner angelegt. Nur hier soll das Skript später arbeiten. Ist das denn nicht irgendwie mit einem Shell-Kommando realisierbar?
Mehr als vor jedem gravierenden Kommando den am Anfang per pwd gespeicherten Pfad mit selbigem Kommando zu überprüfen fällt mir hier leider nicht ein.
Ich möchte es später so haben, dass die Datei möglichst überall aufgerufen werden kann. Unter UNIX geht es, unter Windows dank Cygwin auch.
Wie sieht es mit Mac aus? Da ist ja auch ein Unix - aber haben die auch ein /tmp-Verzeichnis?
Ja. Soweit ich das sehe ist /tmp ein Symlink auf /private/tmp und wie üblich für jeden beschreibbar.
Dann könnte ich mir z. B. unter /tmp/emff ein Arbeitsverzeichnis anlegen.
Ist empfehlenswert, ja.
Einen schönen Mittwoch noch.
Gruß, Mathias
hallo Marc,
Nun möchte ich aber mehrere Bedingungen angeben
Das heißt, du möchtest etwas einsetzen, was wir als "Operatoren" kennen? && und || gibts auch für die Shell, eine recht gute Übersicht findest du in Selflinux - ich finde überhaupt das Kapitel zur Shellprogrammierung ganz aufschlußreich.
Grüße aus Berlin
Christoph S.
Hallo Christoph,
Nun möchte ich aber mehrere Bedingungen angeben
Das heißt, du möchtest etwas einsetzen, was wir als "Operatoren" kennen? && und || gibts auch für die Shell, eine recht gute Übersicht findest du in Selflinux - ich finde überhaupt das Kapitel zur Shellprogrammierung ganz aufschlußreich.
Jepp, werde ich mir zu Gemüte führen. :-)
Ich probiere gerade, eine Lösung für die anderen beiden Probleme zu finden:
Die beiden Probleme sind etwas kniffliger als das erste, welches ich durch die richtige Schreibweise schnell lösen konnte.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc.
- Den Befehl "rm -rf *" möchte ich so abändern, dass alle Dateien im aktuellen Verzeichnis gelöscht werden - bis auf die Datei "IMPORTANT".
Die Lösung in diesem Thread funktioniert bei mir:
$ find ! -name IMPORTANT -exec rm -f {} ;
Problem:
rm: Weder „.“ noch „..“ kann gelöscht werden
Vielleicht gibt es auch hierfür eine Lösung …
Einen schönen Mittwoch noch.
Gruß, Mathias
Hallo Mathias,
- Den Befehl "rm -rf *" möchte ich so abändern, dass alle Dateien im aktuellen Verzeichnis gelöscht werden - bis auf die Datei "IMPORTANT".
Die Lösung in diesem Thread funktioniert bei mir:
$ find ! -name IMPORTANT -exec rm -f {} ;
Problem:
rm: Weder „.“ noch „..“ kann gelöscht werden
Vielleicht gibt es auch hierfür eine Lösung …
Es gibt noch eine bessere, die gerade weiter unten auf der von dir verlinkten Seite steht... :-)
Bei mir funktioniert in der bash folgender Befehl ohne Probleme:
rm -rf !(IMPORTANT)
Sehr schön, sehr schön. Jetzt muss ich nur noch dafür sorgen, dass das Skript immer nur mit ./createskin.sh aufgerufen wird, und nicht etwa mit bin/createskin.sh oder ähnlich...
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo nochmals,
Bei mir funktioniert in der bash folgender Befehl ohne Probleme:
rm -rf !(IMPORTANT)
Der Befehl funktioniert zwar wunderbar von der Bash aus, aber nicht, wenn er aus einem Shell-Skript heraus aufgerufen wird. Dann werde ich wohl einfach mit rm -rf * arbeiten, und ein Arbeitsverzeichnis unter /tmp anlegen, wo dann alles gelöscht wird. Das scheint die absolut beste Lösung zu sein.
Ich muss nur noch dafür sorgen, dass das Skript abbricht, wenn es /tmp/emff nicht erzeugen oder wenn es nicht mit cd nach /tmp/emff wechseln konnte.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo an alle,
ich lege jetzt doch kein Verzeichnis /tmp/emff an, weil swfmill mir dann Probleme bereitet. Im Endeffekt habe ich jetzt eine gute Lösung gefunden:
1. Der Ordner ../temp/ wird angelegt.
2. Anschließend wird in diesen Ordner gewechselt.
3. Nun wird in diesem Ordner gearbeitet.
4. Anschließend wird der Ordner wieder gelöscht.
Auf diese Art und Weise erreiche ich es in jedem Fall, dass ich ein eigenes temporäres Verzeichnis habe. Super, jetzt kann ich endlich mit der Entwicklung des EMFF weitermachen! :-)
Hier die aktuellste Version des Codes (leider gibt es hier im Forum kein Syntax-Highlighting für Shell-Skripte):
<code file="createskin.sh">
#!/bin/bash
binarymtasc="mtasc"
classpath="/usr/local/bin/std/"
binaryswfmill="swfmill"
mtascflags="-version 6 -strict -wimp -header 600:400:31"
tempcompilation="compilation.temp.swf"
inputmtasc="Skin.as"
inputswfmill="swfmill.xml"
tmpdir="../temp/"
clearUp() {
cd ..
if [ -d temp ]
then
rm -rf temp
fi
}
if [ "$1" == "" ]
then
echo "usage: $0 <name of skin>"
echo " example: $0 standard"
exit 0
fi
if [ -d "../skins/$1/" ] && [ -f "../skins/$1/$inputmtasc" ] && [ -f "../skins/$1/$inputswfmill" ]
then
echo -n
else
echo "the found directory seems to be no valid skin directory, aborting"
exit 1
fi
if mkdir $tmpdir 2>/dev/null
then
echo -n
else
echo "could not create $tmpdir, aborting"
exit 1
fi
if cd $tmpdir 2>/dev/null
then
echo -n
else
echo "fatal: could not change working directory to $tmpdir, aborting"
exit 1
fi
cp -rf ../skins/$1/* ./
$binarymtasc -cp $classpath -cp ../code/ $mtascflags $inputmtasc -swf $tempcompilation
$binaryswfmill simple $inputswfmill "../skins/emff_$1.swf"
clearUp
exit 0
</code>
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc.
- Der Ordner ../temp/ wird angelegt.
Und was, wenn ich dein Script direkt in ~ ausführe? Auf das /home–Verzeichnis habe ich keinen Schreibzugriff.
Einen schönen Donnerstag noch.
Gruß, Mathias
Hallo Mathias,
- Der Ordner ../temp/ wird angelegt.
Und was, wenn ich dein Script direkt in ~ ausführe? Auf das /home–Verzeichnis habe ich keinen Schreibzugriff.
Dann wird der Ordner eben nicht angelegt, und das Skript wird sofort gestoppt.
Das Skript ist einfach nicht dafür gedacht, dass man es von überall aufruft - sondern nur im bin-Verzeichnis des EMFF-Ordners.
Vielleicht verstehst du das Ganze besser, wenn du dir das Komplettpaket mal anschaust:
http://dev.marcreichelt.de/emff/emff_0.5_dev_2006-08-17_0.tar.bz2
Natürlich müssen swfmill und mtasc installiert sein, um das Skript auszuführen. ;-)
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc.
Vielleicht verstehst du das Ganze besser, wenn du dir das Komplettpaket mal anschaust:
http://dev.marcreichelt.de/emff/emff_0.5_dev_2006-08-17_0.tar.bz2
Achso, das bin–Verzeichnis ist direkt in deinem Archiv enthalten.
Natürlich müssen swfmill und mtasc installiert sein, um das Skript auszuführen. ;-)
Letzteres gibt es schon im Repository, aus ersterem müsste ich erst ein Paket bauen. Schaue ich mir bei Gelegenheit vielleicht einmal genauer an.
Einen schönen Donnerstag noch.
Gruß, Mathias