Arbeitsweise dieses Shellscript

  • Hallo liebe Leute.
    Ich bräuchte mal eine Hilfe bei dem unteren Quellcode. Ich habe ihn mir von zwei Internetseiten zusammenkopiert und den Pfad und den Text angepasst. Es wurde von mir in den Autostart aufgenommen und startet beim booten ein C-Programm. Funktioniert auch alles, allerdings verstehe ich nicht so ganz wie dieses Script funtioniert und muss es evt. erklären. Lektüre habe ich mir zur genüge bestellt aber das dauert wohl noch ein paar Tage bis die Bücher da sind. Vielleich findet sich ja jemand der mir kurz erklären will was hier passiert.

    Die ersten beiden Zeilen, dient dort die # wie in anderen Programmen zum auskommentieren?
    touch /var/lock/schachprogramm schreibt nur das loggen mit um später nachzuvollziehen wann und von wem es ausgeführt wurde?
    $1 wird ein Argument sein welches erwartet wird, wie sieht dieses aus und woher kommt es?

    #!/bin/sh
    #/etc/init.d/schachprogramm

    touch /var/lock/schachprogramm

    case "$1" in
    start)
    echo "Starte Schach..."
    /home/pi/Desktop/projektschach/schach //pfad der zu öffnenden Datei
    ;;
    stop)
    echo "Beende Schach..."
    killall schach
    ;;
    *)
    echo "Usage:/etc/init.d/schachprogramm{start/stop}"
    exit 1
    ;;
    esac
    exit 0


    Lieben Gruß
    Sebastian

    Einmal editiert, zuletzt von Sebastian (14. Februar 2014 um 13:04)


  • Die ersten beiden Zeilen, dient dort die # wie in anderen Programmen zum auskommentieren?


    ja und nein. Die erste Zeile legt fest, welche shell benutzt wird um das Script auszufuehren. Die zweite Zeile ist wirklich auskommentiert.

    Zitat


    touch /var/lock/schachprogramm schreibt nur das loggen mit um später nachzuvollziehen wann und von wem es ausgeführt wurde?


    nein, so ein lock file dient eigentlich dazu um dafuer zu sorgen, dass ein Programm nur einmal ausgefuehrt wird. Warum man das Schach nicht zweimal ausfuehren koennen soll verstehe ich aber nicht.

    Zitat


    $1 wird ein Argument sein welches erwartet wird, wie sieht dieses aus und woher kommt es?


    Sie mal weiter unten. Da wird ein Hilftext ausgegeben ;)


  • $1 wird ein Argument sein welches erwartet wird, wie sieht dieses aus und woher kommt es?

    Argumente oder auch Parameter sind durch Leerzeichen getrennt. So wäre zum Beispiel ls der Befehl und -la der erste Parameter/Argument/Option der an den Befehl übergeben wird. Bei ls -la /home wäre /home der 2. Parameter...
    Jedes Parameter hat also eine Stelle, das erste Parameter wäre $1 , das zweite wäre $2 , das dritte $3 usw

    Noch eine beiläufige Anmerkung die zum Verständnis beiträgt:

    Scripts werden generell von oben nach unten abgearbeitet.
    Bei einigen anderen Programmiersprachen wird erst der gesammte Code eingelesen und verifiziert, aber dann trotzdem von oben nach unten abgearbeitet


    Bash
    #!/bin/sh

    Das ist der sog. Shebang über den festgelegt wird womit der nachfolgende Code interpretiert bzw verarbeitet werden soll. In diesem Fall wäre das also /bin/sh

    Code
    #/etc/init.d/schachprogramm

    Das hier ist nur ein Kommentar, offensichtlich das Ursprüngliche Script für den Bootvorgang..

    Code
    touch /var/lock/schachprogramm

    Mit touch wird eine Leere Datei erzeugt, oder der Zeitstämpel einer vorhanden Datei auf den aktuellen Wert gesetzt.
    Da /var/lock/ ein flüchtiges Verzeichnis ist, welches nach Reboot geleert wurde - und dem Namen zufolge für das Sperren von Sachen genutzt wird - diente dies anscheint dazu sicher zu stellen dass das Programm nicht mehrmals gestartet wird. Bedeutet: Das Programm oder ein anderes Script prüfte vermutlich ob hier diese Datei existiert und wenn ja würde es annehmen dass das Programm bereits ausgeführt wird und würde somit ein erneutes Starten verweigern... Ob du das tatsächlich brauchst kann ich aber nicht beurteilen weil ich den Rest nicht kenne..

    Code
    case "$1" in

    Das hier ist eine "Fall" Schleife die das erste Parameter, was an das Script übergeben wurde, überprüft und dann eine entsprechene Aktion ausführt...

    Code
    start)
    echo "Starte Schach..."
    /home/pi/Desktop/projektschach/schach   //pfad der zu öffnenden Datei
    ;;

    Das hier ist der erste "Fall". Wenn $1 also "start" wäre, würde er das nach ) ausführen... In diesem Fall wirft er ein echo aus: "Starte Schach..." und führt anschließend ein Script oder Programm aus... Danach wird dieser "Fall" mit ;; beendet

    Code
    stop)
    echo "Beende Schach..."
    killall schach
    ;;

    Das hier ist der zweite "Fall". Wenn $1 also "stop" wäre würde er das nach ) ausführen... In diesem Fall wirt er ein echo aus: "Beende Schach..." und killt anschließend alle Prozesse namens "schach"

    Code
    *)
    echo "Usage:/etc/init.d/schachprogramm{start/stop}"
    exit 1
    ;;

    Das hier ist der dritte "Fall" der durch das Sternchen auf alles andere zutrifft sofern eines der anderen dadrüber stehenden nicht bereits zugetroffen hatte! Wird also nur ausgeführt wenn $1 nicht "start" oder nicht "stop" wäre. Und was das macht ist eben auszugeben wie das Script zu benutzen wäre, wobei das in diesem Fall etwas fehlerhaft ist da ein Leerzeichen nach dem Scriptnamen fehlt... Korrekter wäre also: echo "Usage:/etc/init.d/schachprogramm {start/stop}"
    Auch macht man das für gewöhnlich etwas anders in dem man anstatt den "hardcoded" also fest vorgegebenen Scriptnamen festlegt stattdessen das ein bischen flexibler macht und stattdessen $0 angibt.
    $0 ist der Name des Scripts bzw dessen Aufruf. Wenn du das Script also als /etc/init.d/bla gespeichert hast und es auch so aufrufst:

    Code
    /etc/init.d/bla


    Dann würde in $0 auch genau das hinterlegt sein: /etc/init.d/bla
    Also schöner sähe das ganze so aus:

    Code
    *)
      echo "Usage: $0 {start/stop}"
      exit 1
    ;;

    Achja: Das exit 1 sorgt dafür dass das Script vorzeitig beendet wird, es also nicht weiter verarbeitet wird und mit einem Returncode 1 beendet wird. Es gibt verschiedene Exit Codes aber ums hier nicht zu strapazieren brauchst du eigentlich nur zu wissen das 0 -> alles oke bedeutet und alles über 0 würde bedeutet das irgendwas schief ging ;)
    exit 1 sagt in diesem Fall halt aus dass das übergebene Parameter nicht korrekt war

    Code
    esac
    exit 0

    Überall wo ein case geöffnet wurde muss es auch wieder geschlossen werden. Das wie auch bei if Schleifen so.
    case rückwärts: esac
    if rückwärts: fi

    Anders aber bei while oder for Schleifen, die werden mit done geschlossen


    Das exit 0 ist insbesondere bei init.d Scripts wichtig damit beim Bootvorgang eindeutig festgestellt werden kann ob das Script erfolgreich beendet wurde (der Exitcode kann durch $? abgefragt werden, aber das nur nebenbei erwähnt)

  • Super vielen Dank für die ausführliche Beschreibung :D
    framp: Das schach muss nur einmal ausgeführt werden. Sinn und zweck der Sache ist es ein C-Programm beim bootvorgang zu starten in einem Runlevel wo es nicht möglich oder nötig ist sich als User einzuloggen. Der Pi bootet sobald er mit Spannung versorgt wird und öffnet das dieses C-Programm. In diesem wird ein Server Socket geöffnet und von einem Notebook werden Befehle empfangen und abgearbeitet. Dieses Programm dient dazu einen Schachroboter zu steuern. Vom Notebook gibt es auch eine übergabe zum Beenden woraufhin das C-Programm den Serversocket schließt und den Pi herunterfährt.

    Ist dieses Script in diesem Umfang nötig für mein Vorhaben oder reicht da schon weniger? Denn beendet und heruntergefahren wird ja nicht über das Script sonder vom C-Programm aus.

    Lieben Gruß
    Sebastian

  • Die Initscripts benutzt man normalerweise fuer Systemservices. Das schoene ist, dass man da Dependencies untereinander definieren kann, d.h. z.B. dass von Netz anhaengige Services erst starten, wenn das Netz gestartet wurde.

    In Deinem Falle reicht es eigentlich, wenn Du den Start Deines Programmes in die /etc/rc.local eintraegst. Wichtig ist das Programm dann in den Background mit & zu schicken. Also z.B. die folgende Zeile in /etc/rc.local einfuegen:

    Code
    /usr/local/bin/schach &

    Es geht natuerlich auch per Initscript.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!