首页 文章

作为守护程序运行程序返回错误的pid

提问于
浏览
3

我有一个名为lightid的专有程序,我想将它作为一个守护进程运行 . lightid的开发人员在命令行选项中添加了一个"-d"开关,以便能够将其作为守护进程运行 . 使用sample-service-script,我创建了一个正确的启动/停止bash脚本并将其安装为服务,以便能够使用服务lightid启动服务lightid停止服务lightid状态等来控制它...最重要的是这样我可以检查它的状态使用monit . bash脚本的启动函数(将放在/etc/init.d/lightid中)看起来像这样

SCRIPT="/home/foo/lightid -d"
RUNAS=giulio
NAME=lightid
PIDFILE=/var/run/$NAME.pid
LOGFILE="/dev/null"
CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
su -c "$CMD" $RUNAS > "$PIDFILE"

正如您所看到的,su命令应该返回守护进程的pid,以便可以将其写入$ PIDFILE,并且可以使用PID = $(cat $ PIDFILE)ps axf |来检查其状态 . grep $ |使用kill -15 $(cat“$ PIDFILE”)可以杀死grep -v grep和守护进程

问题是 su -c "$CMD" $RUNAS > "$PIDFILE" 上面的行写入 $PIDFILE 一个pid,它与后台运行的进程不同 . 例如,它将返回9933,而在后台运行的进程将返回pid = 9935 . 实际的pid始终是返回值2.我向开发人员询问了它的"-d"切换实际上做了什么,以及这是否可能是某种原因导致实际pid与su返回的pid不同 . 事实上,我怀疑返回的pid是父进程之一,它在fork之后立即终止.2650359_本身 . 他回答我

“我按照我的方式创建守护进程的原因是因为这是Michael Kerrisk的书”Linux编程接口“中记录的内容 . 他给出的理由是:1 . )通过分叉和终止父进程,子进程成为init进程的子进程2.)孩子需要调用setsid来启动一个新会话并从控制终端中解放出来.3 . )第二个分支确保进程不是会话负责人,因此不能重新获取控制终端(系统) V要求) . 我从来没有遇到过创建守护进程的方法而没有分叉,因此以你想要的方式获得进程PID的问题,我担心,这不是我之前处理过的事情 . “

有什么方法可以得到正确的pid吗?我应该通过适当地将stdin,stdout和stderr重定向到/ dev / null来在非守护进程模式下运行lightid吗?

1 回答

  • 2

    就像你正确地推断出来一样,问题是你的脚本守护着点亮lightid服务的lightid启动器 .

    由于您正在守护守护进程而不是实际服务,因此最终会出现错误的pid .

    您应确保只涉及一个守护程序 . 如果 lightid 支持本机编写pid文件,只需使用其功能即可 .

    如果没有,你应该使用一个用于守护事物的工具,比如 daemon ,让它运行一个非守护进程的lightid . 这些工具重定向fds,创建会话,重置信号处理程序以及休闲守护程序脚本将忘记的所有其他内容 .

相关问题