
Ich habe ein Skript als Dienst in /etc/init.d/myfile geladen
Beim Versuch, den Dienst zu starten, erhalte ich die Fehlermeldung
/etc/init.d/myservice: 21: /etc/init.d/myservice: Syntax error: "(" unexpected
Das Problem scheint an der Prozessersetzung <( im Quellbefehl zu liegen. Ich verwende sie problemlos in anderen Skripten, um Variablen aus meiner Hauptkonfigurationsdatei zu extrahieren, aber innerhalb einer Case-Anweisung weiß ich nicht, wie ich sie zum Laufen bekomme.
meinservice enthält:
#!/bin/sh
#/etc/init.d/myservice
### BEGIN INIT INFO
# Provides: myservice
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: my service
# Description: Start the myservice service
### END INIT INFO
case "$1" in
start)
# start processes
# Import the following variables from config.conf: cfgfile, dir, bindir
source <(grep myservice /opt/mysoftware/config.conf | grep -oP '.*(?= #)')
if [ -f $cfgfile ]
then
echo "Starting myservice"
/usr/bin/screen -U -d -m $bindir/myscript.sh $cfgfile
else
echo "myservice could not start because the file $cfgfile is missing"
fi
;;
stop)
# kill processes
echo "Stopping myservice"
screen -ls | grep Detached | cut -d. -f1 | awk '{print $1}' | xargs kill
;;
restart)
# kill and restart processes
/etc/init.d/myservice stop
/etc/init.d/myservice start
;;
*)
echo "Usage: /etc/init.d/myservice {start|stop|restart}"
exit 1
;;
esac
exit 0
Die Datei config.conf ist eine Liste von Variablendeklarationen mit einer kurzen Beschreibung und dem Namen des Skripts, das sie verwendet. Ich verwende Grep-Filter, um nur die Variablen zu finden, die ich für ein bestimmtes Skript benötige.
Es sieht aus wie das:
var1=value # path to tmp folder myservice
var2=value # log file name myservice script1.sh script2.sh
var3=value # prefix for log file script1.sh script2.sh
Hinweis: Der Dienst funktionierte einwandfrei, bevor ich ihn so konvertierte, dass er die Konfigurationsdatei anstelle von fest codierten Werten verwendete.
Danke schön.
Antwort1
Bash, ksh93, zsh und andere aktuelle Shells unterstützen Prozesssubstitution (die <(command)
Syntax), es handelt sich jedoch um eine nicht standardmäßige Erweiterung. Dash ( /bin/sh
auf Ubuntu-Systemen vorhanden) unterstützt dies nicht, und bash unterstützt dies /bin/sh
auch nicht, wenn es aufgerufen wird.
Wenn Sie Bash zur Verfügung haben, ändern Sie die erste Zeile Ihres Skripts beispielsweise in #!/bin/bash
.
[Auf Systemen, die Bash in einem Verzeichnis auf einem mountbaren Dateisystem haben, wie beispielsweise /usr/local/bin
auf einigen Systemen, müssen Sie möglicherweise sicherstellen, dass das Dateisystem verfügbar ist, bevor Ihr Dienst gestartet wird.]
Antwort2
Prozesssubstitutionist einBashismus, aber deinShebang-Linieist #!/bin/sh
. Sofern es /bin/sh
sich nicht um Bash oder eine andere Shell handelt, die Prozesssubstitution unterstützt, wird diese Syntax tatsächlich nicht unterstützt, wie in@MarkPlotnick.