我有这个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
事实上,正如已接受的答案中提到的那样,可以使用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