从完整的 init.d 脚本(SysV 样式)或从 rc.local 文件的简单单行调用启动正在进行的(类似服务的)进程时,我遇到了一个特殊的问题,如下所示:
su someuser -c "/home/someuser/watchdog.sh &"
watchdog.sh 包含以下内容:
#!/bin/bash
cd /home/someuser
until ./eventMonitoring.py
do
echo "Program crashed with exit code $?. Starting again..." >&2
sleep 1
done
我总是在进程列表中留下一个额外的进程:
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
如果我从我的 init.d 脚本启动它(来源:https ://github.com/ivankovacevic/userspaceServices )
我得到了相同的过程,但它是startpar -f -- userspaceServices
这个过程是什么鬼?为什么在查看 startpar 的手册页时没有提到-f参数?在以另一个用户身份在启动时启动进程方面我做错了什么,这个奇怪的 startpar 进程也需要保留(或启动)?为什么任何其他 init.d 脚本都不存在该进程?
有人可以帮我解释一下这个问题吗?
注意:我的系统是 Debian Wheezy 7.4.0
更新 !
我在 stackoverflow 上提出了一个新问题,从程序员的角度讨论startpar行为:
https ://stackoverflow.com/questions/22840360/figuring-out-what-startpar-c-sysvinit-is-doing
我对此的进一步调查使我找到了解决方案。所以现在我知道如何正确地做到这一点,但我仍然不明白为什么startpar 的行为如此。因此,如果有人愿意介入并解释这一点,我更愿意接受这个答案而不是这个答案。
基本上问题是我调用脚本时没有将标准输入、标准输出和标准错误重定向(或关闭)到文件或 /dev/null 并且出于某种原因startpar(“用于并行运行多个运行级脚本” ) 进程,据我了解,它是在启动期间启动其他进程的进程,因此在我的这个脚本上被阻止。它确实启动了我的脚本,但它本身并没有完成运行,而是停留在进程列表中显示的阶段:
startpar的源代码在这里:http ://svn.savannah.nongnu.org/viewvc/startpar/trunk/startpar.c?root=sysvinit&view=markup
我浏览了一下,并在我发布在 stackoverflow 上的一个新问题中进行了初步分析。在我在这里添加到我的问题的更新中找到链接。
我使用的最终解决方案是:
su - 将用户身份替换为someuser
-c - su 参数以运行指定的命令
nohup - 运行不受挂断影响的命令。防止父进程终止子进程的情况。在这里添加以防万一。但实际上对我的特定情况没有影响。是否需要取决于环境(检查shopt)
>/dev/null - 将标准输出重定向为空,基本上禁用它。
2>&1 - 将标准错误 (2) 输出重定向到标准输出 (1),它被重定向到 null
& - 分离到后台,这会将标准输入也重定向到 /dev/null。
查看在我的系统上运行的其他已知守护程序的文件描述符,我发现重定向到 /dev/null 是很常见的事情。而且只有一些守护进程实际上完全关闭了标准输入、标准输出、标准错误。例如,可以通过以下方式实现:
在实际意义上,它们都是一样的,并且需要(任一选项)将进程干净地分离为后台守护进程。