Ich habe ein node.js-Skript, das beim Booten und unter dem Benutzer www-data ausgeführt werden muss. Während der Entwicklung habe ich das Skript immer gestartet mit:
su www-data -c 'node /var/www/php-jobs/manager.js
Ich habe genau gesehen, was passiert ist, der manager.js funktioniert jetzt super. Suche nach SO Ich habe festgestellt, dass ich dies in meinen /etc/rc.local
einfügen muss. Außerdem habe ich gelernt, die Ausgabe auf eine Protokolldatei zu verweisen und den 2>&1
an "stderr an stdout umleiten" anzuhängen, und er sollte ein Daemon sein, sodass das letzte Zeichen ein &
ist.
Schließlich sieht mein /etc/rc.local
so aus:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
su www-data -c 'node /var/www/php-jobs/manager.js >> /var/log/php-jobs.log 2>&1 &'
exit 0
Wenn ich das selbst ausführe (Sudo /etc/rc.local
): ja, es funktioniert! Wenn ich jedoch einen Neustart durchführe, wird kein node
-Prozess ausgeführt, der /var/log/php-jobs.log
ist nicht vorhanden und daher funktioniert die Datei manager.js nicht. Was ist los?
Ich endete mit upstart , was gut funktioniert.
In diesem Beispiel eines rc.local-Skripts verwende ich die io-Umleitung in der ersten Zeile der Ausführung meiner eigenen Protokolldatei:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exec 2> /tmp/rc.local.log # send stderr from rc.local to a log file
exec 1>&2 # send stdout to the same log file
set -x # tell sh to display commands before execution
/opt/stuff/somefancy.error.script.sh
exit 0
Bei einigen Linux-Systemen (Centos & RH, z. B.) ist /etc/rc.local
anfangs nur eine symbolische Verbindung zu /etc/rc.d/rc.local
. Wenn auf diesen Systemen der symbolische Link unterbrochen wird und /etc/rc.local
eine separate Datei ist, werden Änderungen an /etc/rc.local
beim Booten nicht angezeigt - der Boot-Prozess führt die Version in /etc/rc.d
aus. (Sie funktionieren, wenn Sie /etc/rc.local
manuell ausführen, werden jedoch beim Booten nicht ausgeführt.)
Klingt wie auf Dimadimas System, es sind separate Dateien, aber /etc/rc.d/rc.local
ruft /etc/rc.local
auf
Der symbolische Link von /etc/rc.local
zum 'echten' in /etc/rc.d
kann verloren gehen, wenn rc.local
in ein Sicherungsverzeichnis verschoben wird und es zurückkopiert oder neu erstellt wird, ohne dass das Original in /etc
nur ein symbolischer Link war.
In Ubuntu ist mir aufgefallen, dass es 2 Dateien gibt. Der eigentliche ist /etc/init.d/rc.local
; es scheint, dass der andere /etc/rc.local
ein falscher ist?
Nachdem ich das richtige (/etc/init.d/rc.local
) geändert hatte, wurde es genau wie erwartet ausgeführt.
Möglicherweise haben Sie dies auch erreicht, indem Sie den vollständigen Pfad zum Knoten angeben. Wenn Sie einen Shell-Befehl als Daemon ausführen möchten, sollten Sie stdin außerdem schließen, indem Sie vor dem & 1 1 hinzufügen.
Ich hatte das gleiche Problem (unter CentOS 7) und habe es behoben, indem ich Ausführungsberechtigungen für/etc/local erteilte:
chmod +x /etc/rc.local
wenn Sie Linux in der Cloud verwenden, haben Sie normalerweise keine Möglichkeit, die echte Hardware mit Ihren Händen zu berühren. Daher wird die Konfigurationsoberfläche beim ersten Start nicht angezeigt und kann natürlich nicht konfiguriert werden. Folglich ist der firstboot
-Dienst immer im Weg zu rc.local
. Die Lösung ist, firstboot
zu deaktivieren, indem Sie Folgendes tun:
Sudo chkconfig firstboot off
wenn Sie nicht sicher sind, warum Ihr rc.local
nicht ausgeführt wird, können Sie immer die /etc/rc.d/rc
-Datei überprüfen, da diese Datei immer ausgeführt wird und andere Subsysteme (z. B. rc.local) aufruft.
Ich benutze CentOS 7.
$ cd /etc/profile.d
$ vim yourstuffs.sh
Geben Sie Folgendes in Ihr Script yourstuffs.sh ein.
geben Sie ein, was Sie hier ausführen möchten
export LD_LIBRARY_PATH=/usr/local/cuda-7.0/lib64:$LD_LIBRARY_PATH
Speichern Sie das Betriebssystem und starten Sie es neu.
Ich habe mein Skript zum Laufen gebracht, indem ich /etc/rc.local
editierte und dann die folgenden 3 Befehle gab.
Sudo mv /filename /etc/init.d/
Sudo chmod +x /etc/init.d/filename
Sudo update-rc.d filename defaults
Jetzt arbeitet das Skript beim Booten.
Ich habe in der Vergangenheit rc.local verwendet. Aus meiner Erfahrung habe ich jedoch gelernt, dass Sie das Skript beim Systemstart am zuverlässigsten ausführen können, wenn Sie den Befehl @reboot in crontab verwenden. Zum Beispiel:
@reboot path_to_the_start_up_script.sh
Ich verstehe, dass Sie, wenn Sie Ihr Skript in einer bestimmten RUN-Ebene platzieren, ln -s verwenden sollten, um das Skript mit der Ebene zu verknüpfen, in der es arbeiten soll.
Ich fand heraus, dass es manchmal fehlschlug, weil ich in meinem rc.local
Einen netzwerkorientierten Befehl verwendete. Ich habe das behoben, indem ich sleep 3
An den Anfang meines Skripts gesetzt habe. Ich weiß nicht warum, aber es scheint, dass die Netzwerkschnittstellen bei Ausführung des Skripts nicht richtig konfiguriert sind oder so, und dies lässt dem DHCP-Server nur etwas Zeit oder so. Ich verstehe nicht ganz, aber ich nehme an, Sie könnten es versuchen.
Dies wird höchstwahrscheinlich durch eine fehlende oder unvollständige Umgebungsvariable PATH verursacht.
Wenn Sie Ihren ausführbaren Dateien (su und node) vollständige absolute Pfade zur Verfügung stellen, funktioniert dies.
machen Sie das Skript zuerst mit __.Sudo chmod 755 /path/of/the/file.sh
ausführbar, und fügen Sie das Skript in rc.local sh /path/of/the/file.sh
hinzu, bevor Sie mit 0im rc.local beginnen.. mit __.Sudo chmod 755 /etc/rc.local
next ausführbar, um die Verwendung von rc.local zu initialisieren Sudo /etc/init.d/rc.local start
Dadurch wird das rc.localnow neu gestartet Fertig.