Sysvinit
基於 bash 腳本的 init.d 失敗,為什麼?
我有這個
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
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"
進一步閱讀
分析
/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
而不是while
$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
確實,可以使用
DAEMON
with ,DAEMON_ARGS
如已接受的答案所述。這是真的,因為在第二次呼叫受益的情況下do_start_cmd()
呼叫start-stop-daemon
了 2 次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