追加読書

追加読書

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 $execwill be/bin/bash"$@"will be /home/adr/x.sh+は、変数と一緒に使用するのではなく、人がいないctrlmeときにpathname使用する必要があることを意味します。start_daemon()/lib/init/init-d-scriptDAEMON

修正する

また、問題と解決策をより強調しているので、この回答を提供します。一方、結論のこの部分は間違っています。

利用できない場合は、代わりにpathname使用する必要があります。 start_daemon()/lib/init/init-d-script

実際に許可されている答えで述べたように、DAEMONwithを使用できます。これは2回呼び出されたDAEMON_ARGSため正確です。 2番目の呼び出しは次の利点を得ます。 do_start_cmd()start-stop-daemonDAEMON_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

関連情報