Ubuntu Server - Script beim Start ausführen

Paddii

Lt. Commander
Registriert
Okt. 2008
Beiträge
1.346
Hallo zusammen,

ich habe auf meinen FreeNAS System eine VM mit Ubuntu Server laufen und habe nun leider das Problem, dass ich es einfach nicht hinbekomme (auf Ubuntu) ein Script beim Systemstart auszuführen.

Ich habe es bereits mit "sudo crontab -e" probiert und hier "@ReBoot /home/nutzer/sambashare/naroustarten.sh" eingefügt, aber das Script wird einfach nicht gestartet. Auch einen Eintrag in "/etc/rc.local" hatte ich probiert, brachte aber leider keine Besserung.

Das auszuführende Script ist eigentlich recht Simpel und nichts besonderes. Es start nur einen narou.rb Server.

Code:
#!/bin/bash
echo "Starte Narou Server ..."
cd /home/nutzer/sambashare/ && narou web &>> /home/nutzer/sambashare/NarouServerLog.log &

Das script funktioniert zumindest beim manuellen start einwandfrei. Nur den Autostart beim booten bekomme ich einfach nicht hin.

Wäre klasse wenn hier jemand eine Idee hätte wo das Problem liegen könnte. Bin was Linux angeht leider noch ein Anfänger.
 
Executable Flag auf das Script gesetzt? Ansonsten immer das Programm so aufrufen:
Code:
/home/nutzer/sambashare/narou web &>> /home/nutzer/sambashare/NarouServerLog.log &
Wenn Du ein Change-Directory brauchst, würde ich das eher in das Script selbst packen oder so schreiben
Code:
cd /home/nutzer/sambashare/; /home/nutzer/sambashare/narou web 2>&1 >> /home/nutzer/sambashare/NarouServerLog.log &

Man könnte dann nach dem cd anstelle /home/nutzer/sambashare/narou ein ./narou schreiben. Mach ich aber persönlich nicht so, weil dann nicht so ganz sauber ist, wo der Programmaufruf stattfindet, daher ist vollqualifizierte Angabe besser.

Wichtig ist zu verstehen, daß ein Crontab-Aufruf nicht die gleiche Umgebung hat wie ein Login. Beim Login werden beispielsweise bei einer Bash über die Home-Variable .profile oder .bash_profile wichtige Umgebungsvariablen gezogen, die bei der Crontab-Ausführung NICHT vorhanden sind. Sprich, Du mußt diese Umgebungsvariablen im Script unbedingt nochmals setzen.
 
Es muss @ reboot (nur ohne das Leerzeichen) heißen, nicht @ReBoot sofern es nicht eine Autokorrektur des Forums hier war/ist.

Alternativ kannst dir dafür auch eine systemd Unit schreiben. https://wiki.ubuntuusers.de/systemd/Service_Units/

Wichtig in egal welchem Fall: Führst du den Befehl von Hand aus, wird das unter deinem Userkontext gestartet, bei den anderen Methoden als root sofern nicht anders angegeben. Mit der systemd Unit kannst du aber auch user und group mitgeben, bei Cron musst es in die jeweilige Crontab des Users packen und nicht in die systemweite afaik.

edit: @new Account() Autokorrektur des Forums, jetzt angepasst.
 
Die sauberste Methode ist sicherlich, das Init-System deines Servers zu nutzen, also wahrscheinlich systemd. Bau dir eine passende serviceunit. Darüber lässt sich der Dienst bequem beim Systemstart starten (auch abhängig von anderen Diensten/Gegebenheiten), beim Herunterfahren beenden und auch zwischendurch bequem steuern.
 
new Account() schrieb:
das müsste das Forum sein. Was gemeint ist, ist dass Linux case-sensitive ist.
Also es unterscheidet zwischen groß und kleinschreibung.
Also muss "reboot" klein geschrieben sein.
 
PHuV schrieb:
Executable Flag auf das Script gesetzt? Ansonsten immer das Programm so aufrufen:
Code:
/home/nutzer/sambashare/narou web &>> /home/nutzer/sambashare/NarouServerLog.log &
Wenn Du ein Change-Directory brauchst, würde ich das eher in das Script selbst packen oder so schreiben
Code:
cd /home/nutzer/sambashare/; /home/nutzer/sambashare/narou web 2>&1 >> /home/nutzer/sambashare/NarouServerLog.log &

Man könnte dann nach dem cd anstelle /home/nutzer/sambashare/narou ein ./narou schreiben. Mach ich aber persönlich nicht so, weil dann nicht so ganz sauber ist, wo der Programmaufruf stattfindet, daher ist vollqualifizierte Angabe besser.

Wichtig ist zu verstehen, daß ein Crontab-Aufruf nicht die gleiche Umgebung hat wie ein Login. Beim Login werden beispielsweise bei einer Bash über die Home-Variable .profile oder .bash_profile wichtige Umgebungsvariablen gezogen, die bei der Crontab-Ausführung NICHT vorhanden sind. Sprich, Du mußt diese Umgebungsvariablen im Script unbedingt nochmals setzen.

Die Scripts funktioniert so leider nicht. Hatte es ausprobiert, aber das System versteht den (Ruby) Befehl "narou web" dann als Ordner und findet es nicht. Das cd hatte ich eingefügt weil der "narou web" Befehl in diesem Verzeichniss ausgeführt werden muss.

Fehlermeldung:
Code:
-bash: /home/nutzer/sambashare/narou: No such file or directory



snaxilian schrieb:
Es muss @ reboot (nur ohne das Leerzeichen) heißen, nicht @ReBoot sofern es nicht eine Autokorrektur des Forums hier war/ist.

Alternativ kannst dir dafür auch eine systemd Unit schreiben. https://wiki.ubuntuusers.de/systemd/Service_Units/

Wichtig in egal welchem Fall: Führst du den Befehl von Hand aus, wird das unter deinem Userkontext gestartet, bei den anderen Methoden als root sofern nicht anders angegeben. Mit der systemd Unit kannst du aber auch user und group mitgeben, bei Cron musst es in die jeweilige Crontab des Users packen und nicht in die systemweite afaik.

edit: @new Account() Autokorrektur des Forums, jetzt angepasst.

Das war tatsählich das Forum. Habe natürlich "@ reboot" verwendet.

KillerCow schrieb:
Die sauberste Methode ist sicherlich, das Init-System deines Servers zu nutzen, also wahrscheinlich systemd. Bau dir eine passende serviceunit. Darüber lässt sich der Dienst bequem beim Systemstart starten (auch abhängig von anderen Diensten/Gegebenheiten), beim Herunterfahren beenden und auch zwischendurch bequem steuern.

Ich habe mich da jetzt mal rein gelesen, aber leider funktioniert das auch nicht so richtig.

Ich habe jetzt mal eine Unit mit diesem Inhalt erstellt und auch erfolgreich aktiviert. Ist hier vlt. ein Fehler drin?

Code:
[Unit]
Description=Narou Server Starten

[Service]
Type=simple
ExecStart=/home/nutzer/sambashare/naroustarten.sh

[Install]
WantedBy=reboot.target

Sorry wenn ich mich da etwas blöd anstelle. Ist das erste mal das ich mit Ubuntu arbeite.
 
Warum verwendest du nicht als WantedBy=multi-user.target? reboot.target wird beim Reboot so schnell wie möglich ausgelöst. Da du keine Abhängigkeiten definiert hast kann es also auch passieren, dass zum Zeitpunkt der Ausführung der Unit der Netzwerkstack noch nicht da ist o.ä.

Außerdem fehlt nach wie vor eine Angabe des Nutzers. So wie du es schreibst würde die Unit bzw. das Programm als root laufen.
Ich empfehle auch, bei Description etwas kürzeres zu wählen bzw. ohne Leerzeichen

Zu guter letzt: Ein aktivieren einer Unit macht nur dies, es startet die Unit nicht. Was liefert die Ausgabe von systemctl status Narou Server Starten sofern du die Description nicht anpasst?
Lässt er sich starten mittels systemctl start Narou Server Starten? Was liefert die erneute Ausgabe der Statusabfrage nach dem Start?
 
  • Gefällt mir
Reaktionen: PHuV
Paddii schrieb:
Die Scripts funktioniert so leider nicht. Hatte es ausprobiert, aber das System versteht den (Ruby) Befehl "narou web" dann als Ordner und findet es nicht. Das cd hatte ich eingefügt weil der "narou web" Befehl in diesem Verzeichniss ausgeführt werden muss.

Fehlermeldung:
Code:
-bash: /home/nutzer/sambashare/narou: No such file or directory
Das wird nichts "als Ordner verstanden". Die bash versucht die Datei /home/nutzer/sambashare/narou auszuführen und scheitert. Damit es nicht scheitert, muß die Datei A) an der Stelle vorhanden sein und B) ausführbar sein. Die Fehlermeldung sagt uns, dass es an A) scheitert. Würde es an B) scheitern, käme "Permission denied" als Fehler. Schau also nach, WO GENAU sich das startbare Programm "narou" befindet und schreib den Namen inklusive komplettem Pfad in dein Skript.
 
snaxilian schrieb:
Warum verwendest du nicht als WantedBy=multi-user.target? reboot.target wird beim Reboot so schnell wie möglich ausgelöst. Da du keine Abhängigkeiten definiert hast kann es also auch passieren, dass zum Zeitpunkt der Ausführung der Unit der Netzwerkstack noch nicht da ist o.ä.

Außerdem fehlt nach wie vor eine Angabe des Nutzers. So wie du es schreibst würde die Unit bzw. das Programm als root laufen.
Ich empfehle auch, bei Description etwas kürzeres zu wählen bzw. ohne Leerzeichen

Zu guter letzt: Ein aktivieren einer Unit macht nur dies, es startet die Unit nicht. Was liefert die Ausgabe von systemctl status Narou Server Starten sofern du die Description nicht anpasst?
Lässt er sich starten mittels systemctl start Narou Server Starten? Was liefert die erneute Ausgabe der Statusabfrage nach dem Start?

Also bei "systemctl status" und "systemctl start" kommt diese Fehlermeldung:

Code:
Authentication is required to start 'naroustarten.service'.
Authenticating as: admin
Password:
==== AUTHENTICATION COMPLETE ===
Failed to start naroustarten.service: Unit naroustarten.service is not loaded properly: Invalid argument.
See system logs and 'systemctl status naroustarten.service' for details.

Bei status kommt dann

Code:
Warning: The unit file, source configuration file or drop-ins of naroustarten.service changed on disk. Run 'systemctl daemon-reload' to reload units.
● naroustarten.service - Narou Server Starten
   Loaded: error (Reason: Invalid argument)
  Drop-In: /etc/systemd/system/naroustarten.service.d
           └─override.conf
   Active: inactive (dead)

Nov 26 15:18:13 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:21:05 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:21:07 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:21:28 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:21:30 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:23:40 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:23:42 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:24:15 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:24:17 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
Nov 26 15:26:49 ubuntu systemd[1]: naroustarten.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refus
lines 1-17/17 (END)


Wäre die Unit so richtig?

Code:
[Unit]
Description=naroustarten

[Service]
Type=simple
User=admin
ExecStart=/home/nutzer/sambashare/naroustarten.sh

[Install]
WantedBy=multi-user.target


mensch183 schrieb:
Das wird nichts "als Ordner verstanden". Die bash versucht die Datei /home/nutzer/sambashare/narou auszuführen und scheitert. Damit es nicht scheitert, muß die Datei A) an der Stelle vorhanden sein und B) ausführbar sein. Die Fehlermeldung sagt uns, dass es an A) scheitert. Würde es an B) scheitern, käme "Permission denied" als Fehler. Schau also nach, WO GENAU sich das startbare Programm "narou" befindet und schreib den Namen inklusive komplettem Pfad in dein Skript.

Also zumindest im sambashare Ordner ist nichts zum ausführen. Ich hatte narou als ruby anwendung installiert und dann im sambashare Ordner initialisiert. Daher kann ich narou web nur in dem Ordner ausführen da es dort initialsiert wurde, aber es befindet sich keine derarteige Datei in dem Ordner.
 
Zuletzt bearbeitet:
Existiert der User admin denn auf dem System oder nur innerhalb der Anwendung? Systemd verwendet natürlich Systemuser, andere kennt es nicht...
Du brauchst dein Shellscript/Wrapper nicht, du solltest direkt narou web &>> /home/nutzer/sambashare/NarouServerLog.log verwenden können.

Wenn du es manuell von Hand startest: Als welcher User bist du da angemeldet?

Die Start-Fehlermeldung kommt daher, da das .sh Script ja nur einmal ausgeführt werden soll und nur ne Hilfskrücke war/ist um die eigentliche Anwendung zu starten...
Ich behaupte auch mal, die eigentliche Anwendung narou, was auch immer das sein soll, liegt nicht in /home/user/sambashare/ sondern ganz woanders. Den genauen Pfad findest du mit dem Befehl whereis, hier eine kleine Einführung/Anleitung: https://www.howtoforge.com/linux-whereis-command/

Bedenke die goldene Regel eines Forums: Kein Mensch außer dir weiß was du wie installiert und/oder konfiguriert hast. Nur du alleine sitzt vor deiner Tastatur und Monitor und wir haben nur die Informationsfetzen, die du hier lieferst.
 
Noch 2 Dinge, von denen Paddii offenbar falsche Vorstellungen hat:
1. Wenn man ein Programm starten will, indem man seinen Namen(ohne kompletten Pafd vorne dran) in die Shell schreibt und <enter> drückt, spielt es für den Start i.d.R. keine Rolle, in welchem Verzeichnis man sich gerade befindet. Anders als bei MS-DOS und -Windows werden auf einem Linux Programme im aktuellen Verzeichnis in aller Regel NICHT automatisch gefunden. Es werden nur Verzeichnisse nach dem Programm durchsucht, die in $PATH drin stehen und da steht das aktuelle Verzeichnis "." normalerweise (aus gutem Grund) nicht mit drin. Will man auf Linux ein Programm im aktuellen Verzeichnis starten, was nicht in $PATH steht, musst man statt z.B. "narou" den Pfad mit angeben und "./narou" tippen.

2. Wenn man ein Programm aus der Shell starten will, ist es total egal, ob das nun ein ruby- oder perl- oder C- oder sonstwas für ein Programm ist. Es wird schlicht nur nach einem File mit passendem Namen und Ausführungsrecht gesucht.

Was folgt daraus?
Wenn der Aufruf von "narou" in der Shell als normal eingeloggter Nutzer funktioniert, in dem Startskript aber nicht, ist sehr wahrscheinlich $PATH in diesen beiden Fällen unterschiedlich konfiguriert.

Finde also erstmal - wie snaxilian schrieb - mit "whereis -b narou" oder "which narou" heraus, wo das Ding tatsächlich liegt. Dann kann man den kompetten Pad angeben und muß sich nicht mit $PATH rumärgern.
 
Zurück
Oben