Ein Programm mehrmals starten.

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,
    Ich hätte da eine Grundsatzfrage zum Starten von einem Programm mehrmals.
    Als Beispiel nehme ich mal Shairport her. Ich möchte nun Shairport mit unterschiedlichem Port und Soundkarte mehrmals starten.

    Möglichkeit 1:
    Ich würde mir nun ein Script Basteln das beim Booten gestartet wird
    like this:

    Bash
    #!/bin/bash
    /usr/local/bin/shairport -w -a Shairport -d -p 5300 -o alsa -- -d hw:0,0
    /usr/local/bin/shairport -w -a Shairport1 -d -p 5310 -o alsa -- -d hw:1,0

    funktioniert Perfekt.

    Möglichkeit 2:
    Man müsste, wie in diesem Beispiel mit Shairport, die /etc/init.d/shairport Kopieren und umbenenen in zb. shairport01 und den inhalt etwas modifizieren.

    Leider kann ich keinen unterschied erkennen außer, dass Möglichkeit 2 viel, viel umständlicher ist.

    Meine Fragen:
    - Was ist der Unterschied zwischen diesen 2 Versionen?
    - Vor- Nachteile?
    - Gibt es eine Möglichkeit 3,4,5?
    - Wie würdet Ihr das Lösen?


    Vielen DANK!!!

    Einmal editiert, zuletzt von Sevi (7. März 2014 um 10:06)

  • Der Vorteil der 2. Idee liegt auf der Hand. Du kannst beide unabhängig von einander starten bzw. stoppen.
    Ob es andere Möglichkeiten gibt, hängt von den Möglichkeiten des Programms ab. Ein Apache beispielsweise braucht ja nur eine entsprechende Konfig, um auf unterschiedlichen Ports zu lauschen.

    --
    man ist das System-Anzeigeprogramm für die Handbuchseiten von Linux.

  • Okay DANKE für die Antwort.
    Ich bin jetzt nicht so der Linux Fuchs und muss meine Frage jetzt noch ein wenig vertiefen. Abgesehen von den vorteilen der 2. Möglichkeit > Separates starten und stoppen, separater error log, separat ....... Ich meine das alles separat ist, das ist mir nämlich klar, läuft das Programm trotzdem absolut stabil? oder gibt es irgendwelche Leistungseinbußen? Habe ich irgendwelche nachteile wenn ich einen RPi jahrelang so betreibe? Welche Lösung währe die sauberere, professionellere?
    Mir fällt noch ein Vorteil der 1. Möglichkeit ein. Bei einem Update, was bei einem Linuxprogramm sehr häufig der Fall ist, brauche ich dann nicht alle meine Init.d scripte modifizieren oder?

    DANKE!!

  • Wie stabil das Programm läuft hängt nicht vom Start Script ab ;)

    Ich hätte dazu aber noch eine Abwandlung der 2. Möglichkeit die aber vielleicht etwas kompliziert erscheinen mag:

    /etc/init.d/shairport modifizieren sodass für jede Instanz ein eigenes Pid-File erstellt wird. Über dieses pid-File kann man dann punktgenau die entsprechende Instanz beenden

    Am einfachsten wärs halt zu wissen wieviele Instanzen du starten willst und diese dann hardcoded festzulegen - wenn das aber flexibel gestaltet werden solle, wär die Umsetzung komplizierter :)
    Wenn du das aber eh nur 2x starten willst dann bau dir dafür am besten ein eigenes Script


    Mach es so wie du machst ;)

  • Hi together,

    also Linux-konform wäre meines Erachtens die Variante 1. Und ich finde, das sieht auch richtig elegant aus. Sorry, aber die Kopier-/Umbenamsungs-Action hat für mich irgendwie was stümperhaftes.
    Und wenn das Vorgehen nach #2 schon komplizierter und aufwändiger als Ansatz Nr. 1 erscheint, dann kann kann #2 nicht richtig sein ;) ...

    just two cent for the piano man,
    greetz,
    -ds-

  • Sorry, aber die Kopier-/Umbenamsungs-Action hat für mich irgendwie was stümperhaftes.

    ..vorallem wenn man dabei die runlevel links vergisst und lässt, dann hagelts fehlermeldungen :lol:


    Und wenn das Vorgehen nach #2 schon komplizierter und aufwändiger als Ansatz Nr. 1 erscheint, dann kann kann #2 nicht richtig sein ;) ...

    agreed

  • Entschuldigt, nein. Das istr wahrlich nix "stümperhaftes" dran. Es hängt immer davon ab was man möchte oder besser gesagt was das Ziel sein soll.
    Will man die beiden Instanzen getrennt von einander starten/stoppen können, dann ist 2 der einfache effektive und nicht besonders aufwendige Weg.
    Will man einfach nur 2 Instanzen und das starten/stopen kann/soll/muss gleichzeitig passieren, dann ist Veriante 1 völlig ausreichend.

    Man kann es natürlich immer noch versuchen mit 2 configs über ein Skript und 2 PID usw. sich zusammen basteln. Elegant? Hm hängt von der Skriptfähigkeit des USers ab aber in jedem Fall aufwendiger. Deshalb ist Variante 2 schneller und einfacher zu realisieren.

    Und die Linkerei dafür habe ich ja update-rc.

    Gruß Lunepi

    --
    man ist das System-Anzeigeprogramm für die Handbuchseiten von Linux.

  • Mit der start/stopp Geschichte gebe ich Dir - teilweise - recht. Das Problem, das ich sehe ist, dass wenn Du auf Deine Methode eine Instanz (und nicht alle) stoppst, können nicht nachvollziehbare Folgefehler auftreten - z.B. dass Du allen anderen Instanzen irgenwelche Ressourcen unter dem Hintern wegziehst. Also wenn schon so ein Workauraround (wenn der script mehrere Instanzen unterstützen würde, dann wäer das vorgesehen und einfacher) - dann vorsichtig sein ;) ...

    // EDIT:
    was ich noch vergass: in den Jahren, in denen ich mich mit UNIX/Linux beschäftigt habe, habe ich eins gelernt: es muss einfach sein, sonst wird es entweder ein Provisorium oder ein Workaround.


    -ds-

  • Also bevor man an einem /etc/init.d/ Script herum pfuscht sollte man sich lieber selber ein eigenes Script schreiben - ansonsten ist das durchaus stümperhaft

    (ob der TE an update-rc.d gedacht hat oder ihm das überhaupt bekannt ist sei jetzt auch mal dahin gestellt)

    Und Erfahrungsmäßig geht es schneller sich jüst selber ein Script zu schreiben als ein 'fremdes' umzuschreiben - Orientieren kann man sich ruhig an anderen, aber blindes copy&past ist selten wirklich sinnvoll


    So wie ich den TE bisher verstanden habe möchte er einfach nur 2 Instanzen laufen lassen, es spricht also nichts dagegen ein Script irgendwo in $PATH abzulegen und ggf bei Systemstart automatisch mit starten zu lassen...
    Warum irgendwo in $PATH ? -> Wenn er dann start/stop/restart oder was auch immer ausführen will brauch er nicht den vollständigen Pfad ( /etc/init.d/shairport01 start ; /etc/init.d/shairport02 start ) eingeben sondern nur den filename des Scripts
    (an dieser umbenenn Methode fällt nun vllt auch auf wie Umständlich das wäre)

    Wenn es dann aber noch so ist dass shairport, warum auch immer, mal crasht sollte er zusätzlich auch noch einen Watchdog schreiben/einbinden.
    Wenn er abunzu mal einer der beiden shairport Instanzen auch mal für längere Zeit beendet haben möchte, der watchdog ihm aber nicht dazwischen funken soll, bedarf es eben weiterer Anpassungen/Ergänzungen in beiden Scripts damit das gewährleistet ist usw

    Da Wir aber über diese Details wenig bis gar nichts wissen, können wir ihm zu diesem Zeitpunkt auch nicht wirklich weiter helfen oder codesnipsel zeigen wie es gehen könnte - aber generell läßt sich sagen das beinahe alles Möglich ist ;)

  • Vielen DANK! für die reichlichen Antworten.

    Ich habs mir jetzt mal ganz einfach gemacht und ein bash script gemacht, dass mir mehrere Instanzen von Shairplay und Squeezelite mit ein paar Abhängigkeiten startet.

    Das Script funktioniert auch sehr gut nur hab ich ein Problem. Führe ich das Script aus, läuft es ewig weiter, da es auf meine gestarteten Programme wartet die aber natürlich und auch dann hoffentlich ewig laufen. Gibt es eine Möglichkeit dieses Script nach der Letzten zeile unwiderruflich zu stoppen? weil ja meine gestarteten Programme sowieso laufen. Der Befehlt "exit 1" am schluß funktioniert nämlich nicht.


    DANKE!

    Einmal editiert, zuletzt von Sevi (25. März 2014 um 19:59)


  • So wie ich den TE bisher verstanden habe möchte er einfach nur 2 Instanzen laufen lassen, es spricht also nichts dagegen ein Script irgendwo in $PATH abzulegen und ggf bei Systemstart automatisch mit starten zu lassen...
    Warum irgendwo in $PATH ? -> Wenn er dann start/stop/restart oder was auch immer ausführen will brauch er nicht den vollständigen Pfad ( /etc/init.d/shairport01 start ; /etc/init.d/shairport02 start ) eingeben sondern nur den filename des Scripts
    (an dieser umbenenn Methode fällt nun vllt auch auf wie Umständlich das wäre)

    - Stimmt!

    was meinst du mit $PATH ?. Mir sind start scripte die in Init.d liegen bekannt und hab auch schon selber selche erstellt und weiß auch was ein Demonprozess ist nur was meinst du mit $PATH?

    Weiters hab ich noch ein Problem mit Shairport. gib ich

    Code
    /usr/local/bin/shairport -w -p 5201 -a PLAYER01 --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt" -o alsa -- -d airplay01


    in die Kommandozeile ein funktioniert dieser Befehl wunderbar. Doch leider nicht in einem Init.d script. ?????? Es kommt dann eine Fehlermeldung, dass im Init.d Script in der Zeile XX not found wenn ich dann:

    Code
    --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt"


    lösche, also nur:

    Code
    /usr/local/bin/shairport -w -p 5201 -a PLAYER01 -o alsa -- -d airplay01


    eingebe funktioniert das Init.d script wonderbra :s
    an was könnte das liegen?
    Viell. würde das mit dem besagten $PATH mein Problem lösen

    DANKE!!


  • was meinst du mit $PATH ?. Mir sind start scripte die in Init.d liegen bekannt und hab auch schon selber selche erstellt und weiß auch was ein Demonprozess ist nur was meinst du mit $PATH?

    $PATH beinhaltet alle Verzeichnisse in denen Linux nach Befehlen sucht, also wenn du in der Konsole zum Beispiel ls oder mv usw eingibst...
    Die Konsole ist ja normalerweise eine bash Shell. $PATH ist eine globale environment variable die standardmässig folgendes beinhaltet:

    Code
    root@raspberrypi:~# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin


    Als Trennzeichen wird " : " (Doppelpunkt) verwendet.


    Weiters hab ich noch ein Problem mit Shairport. gib ich

    Code
    /usr/local/bin/shairport -w -p 5201 -a PLAYER01 --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt" -o alsa -- -d airplay01


    in die Kommandozeile ein funktioniert dieser Befehl wunderbar. Doch leider nicht in einem Init.d script. ?????? Es kommt dann eine Fehlermeldung, dass im Init.d Script in der Zeile XX not found wenn ich dann:

    Code
    --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt"


    lösche, also nur:

    Code
    /usr/local/bin/shairport -w -p 5201 -a PLAYER01 -o alsa -- -d airplay01


    eingebe funktioniert das Init.d script wonderbra :s
    an was könnte das liegen?

    Poste mal bitte dein init Script

  • DANKE!

    Ich hab jetzt mal nur test weise die DAEMON Variable ausgeklammert und den start Befehl direkt reinkopiert - jetzt jetzt würde es funktionieren aber warum nicht mit der DAEMON Variable :s
    Wenn ich nun Shairplay mehrmals starten möchte, müsste ich nun mehrere Init.d Scripte machen oder? oder gibt es eine etwas bessere Möglichkeit?
    Hier mein Script:

  • Naja init.d Scripts werden immer mit start oder stop aufgerufen, deine /usr/local/bin/shairport Zeile über dem case gehören da also nicht hin und macht das init Script somit kaputt ;)

    Davon abgesehen ist aber auch der Rest fehlerhaft, zB $DAEMON_PATH wird nirgends gesetzt, ON_START/ON_STOP und noch ein paar andere werden nirgends verwendet, PID in start) sieht auch komisch aus, in stop) ist auch ein bisschen Chaos/fehlerhaft und im letzten case *) fehlen die ;; :D
    Oder
    NAME=shairport
    DAEMON=/usr/bin/$NAME
    gibt es anscheint ebenfalls nicht? Dein Path scheint /usr/local/bin/shairport zu sein, dementsprechend schlägt dann auch die Überprüfung ob die Datei existiert und ausführbar ist (if [ ! -x "$DAEMON" ]; then) fehl

    Hast du das copy&past mäßig selber erstellt :huh:

  • hallo,
    also, das war jetzt nur ein versuch. Ich habe natürlich in /var/bin ebenfalls das Shairport Programm hinterlegt (jetzt gerade wirkungslos). Ich habe jetzt schon einige Variablen die nirgends aufgerufen werden weil ich schon ziemlich viel herum experimentiert habe, ist aber meines Wissens auch egal ob da jetzt Variablen sind die nicht geraucht werden, dies ist jetzt meins Erachtens kein Fehler und nicht der Grund warum das Script nicht mit

    Code
    --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt"


    funktioniert.
    weil ohne diesem Eintrag Funktioniert das Shairport ohne Probleme.
    Ich denke, dass es da was mit der Berechtigung hat, kenne mich aber leider nicht gut mit Berechtigung und Init.d Scripten aus.

    also nochmal
    So funktioniert mein Init.d Script Problemlos:

    und möchte (Siehe Code oben) mit einfügen - nur leider kommt dann ein Fehler beim Starten des Init.d Scriptes "Zeile XX not found"

    DANKE!


    [/code]

  • Code
    PID=`/usr/local/bin/shairport -w -p 5201 -a PLAYER01 --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt" -o alsa -- -d airplay01 > /dev/null 2>&1 & echo $!`


    Wenn dann würde ich "&& echo$!" schreiben.
    Weiter würde ich mal testen ob nicht die " escaped werden müssen.

    Ansonsten hat Meigrafd recht, aufgrund $DEAMON startet das skript nicht....

    Ah ok, dann startest du shairport aus /usr/bin/ und dncht /usr/local/bin?

    --
    man ist das System-Anzeigeprogramm für die Handbuchseiten von Linux.

    Einmal editiert, zuletzt von Lunepi (31. März 2014 um 14:50)

  • Zitat

    Wenn dann würde ich "&& echo$!" schreiben.


    hat leider nichts gebracht.

    Zitat

    Weiter würde ich mal testen ob nicht die " escaped werden müssen.


    was meinst du damit?

    Zitat

    Ansonsten hat Meigrafd recht, aufgrund $DEAMON startet das skript nicht....


    mein Script funktioniert ja doch leider nur ohne

    Code
    --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt"

    DANKE!

  • Also && bringt deinem Fehler nix, es schreibt aber erst die PID raus wenn der erste Befehl erfolgreich war.
    Versuchs mal mit:

    Code
    --on-start \"echo 1 > /var/www/src/status_shairplay01.txt\" --on-stop \"echo 0 > /var/www/src/status_shairplay01.txt\"
    
    
    oder
    
    
    --on-start 'echo 1 > /var/www/src/status_shairplay01.txt' --on-stop 'echo 0 > /var/www/src/status_shairplay01.txt'

    --
    man ist das System-Anzeigeprogramm für die Handbuchseiten von Linux.

  • Zitat
    Code
    --on-start \"echo 1 > /var/www/src/status_shairplay01.txt\" --on-stop \"echo 0 > /var/www/src/status_shairplay01.txt\"
    
    
    oder
    
    
    --on-start 'echo 1 > /var/www/src/status_shairplay01.txt' --on-stop 'echo 0 > /var/www/src/status_shairplay01.txt'


    Okay, das hab ich schon probiert - beide Versionen funktionieren leider nicht. Jedoch funktioniert

    Code
    /usr/local/bin/shairport -w -p 5201 -a PLAYER01 --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt" -o alsa -- -d airplay01 > /dev/null 2>&1 & echo $!


    in der Kommandozeile schon :s

    Code
    root@raspberry:~# /usr/bin/shairport -w -p 5201 -a PLAYER01 --on-start "echo 1 > /var/www/src/status_shairplay01.txt" --on-stop "echo 0 > /var/www/src/status_shairplay01.txt" -o alsa -- -d airplay01 > /dev/null 2>&1 & echo $!
    [1] 2774
    2774
    root@raspberry:~#


    DANKE!!

    Einmal editiert, zuletzt von Sevi (31. März 2014 um 15:23)

Jetzt mitmachen!

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