init.d
次のスクリプト()があります/etc/init.d/ctrlme
。
#!/lib/init/init-d-script
### BEGIN INIT INFO
# Provides: ctrlme
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: ctrlme
# Description: ctrlme
### END INIT INFO
# sudo cp -v /home/gigikent/bin/init.d-services/ctrlme /etc/init.d/; sudo chown root: /etc/init.d/ctrlme
#
# https://www.pks.mpg.de/~mueller/docs/suse10.1/suselinux-manual_en/manual/sec.boot.init.html
#
NAME=ctrlme
PIDFILE=/run/ctrlme.pid
DAEMON=/bin/bash -c '/home/gigikent/x.sh ctrlme'
DESC=ctrlme
# . /lib/lsb/init-functions
#
# case "$1" in
# start)
# /home/gigikent/x.sh ctrlme
# ;;
# stop|restart|force-reload)
# exit 0
# ;;
# *) echo "Usage: $0 {start|stop|restart|force-reload}" >&2; exit 1 ;;
# esac
起動に失敗しました:
Jun 16 18:57:13 gigikent.go.ro ctrlme[28454]: /lib/init/init-d-script: 20: /etc/init.d/ctrlme: -c: not found
Jun 16 18:57:13 gigikent.go.ro systemd[1]: ctrlme.service: Succeeded.
-- Subject: Unit succeeded
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- The unit ctrlme.service has successfully entered the 'dead' state.
/bin/bash -c '/home/gigikent/x.sh ctrlme'
コマンドを実行すると、期待どおりに動作します。
なぜこれが起こり、どのように解決するのですか?
システム情報:
Ubuntu 19.04
答え1
DAEMON=/bin/bash -c '/home/adr/x.sh ctrlme'
これはおそらく次のとおりです。
デーモン="/bin/bash" DAEMON_ARGS="'/home/adr/x.sh ctrlme'"
または、より良い方法は次のとおりです。
デーモン="/home/adr/x.sh" DAEMON_ARGS="ctrlme"
追加読書
答え2
観察されたソースを分析します/lib/init/init-d-script
。
do_start_cmd() {
start-stop-daemon --start --quiet ${PIDFILE:+--pidfile ${PIDFILE}} \
$START_ARGS \
--startas $DAEMON --name $NAME --exec $DAEMON --test
スクリプト(bashスクリプトなど)では、次のようには機能しません。http://man7.org/linux/man-pages/man8/start-stop-daemon.8.html DAEMON
する必要がありますpathname
:
-a, --startas pathname
With --start, start the process specified by pathname. If not
specified, defaults to the argument given to --exec.
上記の使用法をの使用法とstart-stop-daemon
比較することもできます/lib/lsb/init-functions
。たとえば、次のようになります。
start_daemon () {
...
exec="$1"; shift
...
if [ "$force" ]; then
/sbin/start-stop-daemon $args \
--chdir "$PWD" --startas $exec --pidfile /dev/null -- "$@"
...
たとえば、次のように使用する場合start_daemon
:
start_daemon -p /run/ctrlme.pid /bin/bash /home/adr/x.sh ctrlme
Than $exec
will be/bin/bash
と"$@"
will be /home/adr/x.sh
+は、変数と一緒に使用するのではなく、人がいないctrlme
ときにpathname
使用する必要があることを意味します。start_daemon()
/lib/init/init-d-script
DAEMON
修正する
また、問題と解決策をより強調しているので、この回答を提供します。一方、結論のこの部分は間違っています。
利用できない場合は、代わりに
pathname
使用する必要があります。start_daemon()
/lib/init/init-d-script
実際に許可されている答えで述べたように、DAEMON
withを使用できます。これは2回呼び出されたDAEMON_ARGS
ため正確です。 2番目の呼び出しは次の利点を得ます。 do_start_cmd()
start-stop-daemon
DAEMON_ARGS
do_start_cmd() {
start-stop-daemon --start --quiet ${PIDFILE:+--pidfile ${PIDFILE}} \
$START_ARGS \
--startas $DAEMON --name $NAME --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet ${PIDFILE:+--pidfile ${PIDFILE}} \
$START_ARGS \
--startas $DAEMON --name $NAME --exec $DAEMON -- $DAEMON_ARGS \
|| return 2