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

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/

--
Linux is like a wigwam - no windows, no gates and an Apache inside!
Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
  1. 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

    --
    sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
    „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
    [HTML Design Constraints: Logical Markup]
    1. 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

      --
      sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
      „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
      [HTML Design Constraints: Logical Markup]
      1. 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

        global options

        path to MTASC binary

        binarymtasc="mtasc"

        path to ActionScript classes for MTASC

        classpath="/usr/local/bin/std/"

        path to swfmill binary

        binaryswfmill="swfmill"

        MTASC compile flags

        mtascflags="-version 6 -strict -wimp -header 600:400:31"

        temporary file for classes compiled by MTASC

        tempcompilation="compilation.temp.swf"

        input file MTASC

        inputmtasc="Skin.as"

        input file swfmill

        inputswfmill="swfmill.xml"

        change to temp directory - this is the only directory where we will work

        cd ../temp/

        check parameter

        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

        execution of commands

        copy all skin files into this temp directory

        cp -rf ../skins/$1/* ./

        create temporary file with compilation created by MTASC

        $binarymtasc -cp $classpath -cp ../code/ $mtascflags $inputmtasc -swf $tempcompilation

        create skin with swfmill

        $binaryswfmill simple $inputswfmill "../skins/$1.swf"

        delete temporary files

        rm -rf *

        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/

        --
        Linux is like a wigwam - no windows, no gates and an Apache inside!
        Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
        1. 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/

          --
          Linux is like a wigwam - no windows, no gates and an Apache inside!
          Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
        2. 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

          --
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
          „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
          [HTML Design Constraints: Logical Markup]
          1. 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/

            --
            Linux is like a wigwam - no windows, no gates and an Apache inside!
            Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
            1. 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

              --
              sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
              „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
              [HTML Design Constraints: Logical Markup]
  2. 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.

    --
    Visitenkarte
    ss:| zu:) ls:& fo:) va:) sh:| rl:|
    1. 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:

      • Das Skript soll auf jeden Fall in dem Verzeichnis arbeiten, wo es liegt, und NICHT unbedingt in dem, woraus es gestartet wird
      • 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 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/

      --
      Linux is like a wigwam - no windows, no gates and an Apache inside!
      Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
      1. 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

        --
        sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
        „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
        [HTML Design Constraints: Logical Markup]
        1. 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/

          --
          Linux is like a wigwam - no windows, no gates and an Apache inside!
          Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
          1. 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/

            --
            Linux is like a wigwam - no windows, no gates and an Apache inside!
            Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
  3. 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

    global options

    path to MTASC binary

    binarymtasc="mtasc"

    path to ActionScript classes for MTASC

    classpath="/usr/local/bin/std/"

    path to swfmill binary

    binaryswfmill="swfmill"

    MTASC compile flags

    mtascflags="-version 6 -strict -wimp -header 600:400:31"

    temporary file for classes compiled by MTASC

    tempcompilation="compilation.temp.swf"

    input file MTASC

    inputmtasc="Skin.as"

    input file swfmill

    inputswfmill="swfmill.xml"

    directory for temporary files

    tmpdir="../temp/"

    clearUp() {
     cd ..
     if [ -d temp ]
     then
      rm -rf temp
     fi
    }

    check parameter

    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

    make temp directory and change the working directory

    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

    execution of commands

    copy all skin files into this temp directory

    cp -rf ../skins/$1/* ./

    create temporary file with compilation created by MTASC

    $binarymtasc -cp $classpath -cp ../code/ $mtascflags $inputmtasc -swf $tempcompilation

    create skin with swfmill

    $binaryswfmill simple $inputswfmill "../skins/emff_$1.swf"

    delete temporary files

    clearUp

    exit 0
    </code>

    Grüße

    Marc Reichelt || http://www.marcreichelt.de/

    --
    Linux is like a wigwam - no windows, no gates and an Apache inside!
    Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
    1. Hallo Marc.

      1. 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

      --
      sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
      „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
      [HTML Design Constraints: Logical Markup]
      1. Hallo Mathias,

        1. 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/

        --
        Linux is like a wigwam - no windows, no gates and an Apache inside!
        Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
        1. 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

          --
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
          „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
          [HTML Design Constraints: Logical Markup]