我尝试使用以下命令启动 ZNC
service znc start
我收到这个错误
Starting znc: /usr/bin/dirname: extra operand `2>&1.pid'
Try `/usr/bin/dirname --help' for more information.
[FAILED]
这就是 init.d 脚本的样子
exec=/usr/bin/znc
prog=znc
config=/var/lib/znc
runas=znc
lockfile=/var/lock/subsys/$prog
start() {
[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
# if not running, start it up here, usually something like "daemon $exec"
daemon --user $runas "$exec -d $config >/dev/null 2>&1"
# If you're reckless with your system, comment the line above and
# uncomment this one below... I just don't get it why
#daemon "$exec -r -d $config >/dev/null 2>&1"
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
任何人都知道什么会导致这种情况。
我运行的是centos
答案1
我根据您问题的代码创建了一个示例初始化脚本,并确定您需要通过将双引号从末尾移动到靠近中间的位置来更改一行:
daemon --user $runas "$exec" -d $config >/dev/null 2>&1
daemon()
中的函数查看/etc/init.d/functions
第一个非参数参数,将程序路径剥离回基本名称,并使用它来派生 PID 锁定文件。通过(错误地)引用整个字符串,PID 文件被错误地确定为2>&1.pid
您的错误所证明的那样。
如果 ZNC 程序不自行守护并分叉到后台,则此处所示的代码行仍将无限期挂起。我没有 ZNC,所以我无法测试这部分,但考虑到 CentOS 守护程序实用程序没有提供后台任务的选项,我希望这一基本要求已在 ZNC 本身中得到解决。
答案2
假设您已经创建了一个新的用户帐户
sudo useradd --system --shell /sbin/nologin --comment "Account to run ZNC daemon" --user-group znc
并且您已经创建了一个配置文件:
CentOS 上的 init.d 脚本应如下所示:
#!/bin/sh
#
# znc - Advanced IRC Bouncer INIT script #
# description: An Advanced IRC bouncer INIT script for
# Source function library.
. /etc/rc.d/init.d/functions
exec=/usr/bin/znc
prog=znc
config=/var/lib/znc
runas=znc
lockfile=/var/lock/subsys/$prog
start() {
[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
# if not running, start it up here, usually something like "daemon $exec"
daemon --user $runas "$exec -d $config >/dev/null 2>&1"
# If you're reckless with your system, comment the line above and
# uncomment this one below... I just don't get it why
# daemon "$exec -r -d $config >/dev/null 2>&1"
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
# stop it here, often "killproc $prog"
killproc $prog -TERM
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
reload() {
echo -n $"Reloading $prog: "
# stop it here, often "killproc $prog"
killproc $prog -HUP
retval=$?
echo
}
restart() {
stop
start
}
rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|reload|restart|condrestart|try-restart}"
exit 2
esac
exit $?
确保chmod +x
它否则你可以使用 crontab 只需添加
*/10 * * * * /usr/bin/znc >/dev/null 2>&1
到你的 crontab ( crontab -e
)
将 10 替换为更低的值以进行更积极的检查
答案3
daemon --user $runas --check $exec "$exec -d $config >/dev/null 2>&1"
。我刚刚添加了--check $exec
.守护程序函数无法znc
从"$exec -d $config >/dev/null 2>&1"
pid 文件中获取/var/run/znc.pid
,它的${1##*/}
计算结果为“null 2>&1”。--check $exec
这确保了它的正确性。
或者你可以通过pidfile=/var/run/$(basename $exec).pid daemon --user $runas --pidfile $pidfile "$exec -d $config >/dev/null 2>&1"
如果整个内容没有像“$exec -d $config >/dev/null 2>&1”那样被引用,则“daemon”函数的stdout和stderr将被重定向,并且“daemon”函数的任何输出消息或错误将不会显示在启动期间。它应该在需要的时候大声喊叫。它不应该被关闭。当被引用时,它作为 '$*' 传递给守护函数,以便 $exec 的 stdout 和 stderr 被正确重定向。单独引用 $exec 不会执行任何操作,除非它的名称或路径中有空格。
系统守护进程不必重定向到 /dev/null,因为它们会关闭所有打开的 FD,并在 0,1 和 2 本身上打开 /dev/null,并与终端分离并使用日志进行输出。在这里,我认为“znc”需要 I/O redir,因为它本身不执行 redir。