进一步阅读

进一步阅读

我有这个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'"

或者,更好的是:

DAEMON =“/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

$exec将是/bin/bash"$@"将是/home/adr/x.sh+ctrlme意味着当没有一个时pathname必须使用start_daemon()而不是/lib/init/init-d-script与它的DAEMON变量一起使用。

更新

我也给出了这个答案,因为它更好地突出了问题和解决方案。另一方面,请注意,结论的这一部分是错误的:

当没有时,pathname必须使用 start_daemon()而不是/lib/init/init-d-script

事实上,正如已接受的答案中提到的那样,可以使用DAEMONwith 。DAEMON_ARGS这是正确的,因为do_start_cmd()调用了start-stop-daemon2 次,其中第二次调用受益于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

相关内容