我在从完整的 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 -- 用户空间服务
那到底是什么过程?为什么没有提到-F查看 startpar 的手册页时,参数是什么?我在以其他用户身份启动进程方面做错了什么,为什么这个奇怪的 startpar 进程也需要保留(或启动)?为什么该进程不存在于任何其他 init.d 脚本中?
有人能帮我阐明一下这个问题吗?
注意:我的系统是 Debian Wheezy 7.4.0
更新 !
我在 stackoverflow 上提出了一个新问题来讨论启动器从程序员的角度来看行为:
https://stackoverflow.com/questions/22840360/figuring-out-what-startpar-c-sysvinit-is-doing
答案1
我对此进行了进一步的研究,找到了解决方案。所以现在我知道如何正确地做到这一点,但我仍然不明白为什么启动器表现得像那样。所以如果有人愿意介入并解释这一点,我更愿意接受那个答案,而不是这个。
基本上,问题是我在调用脚本时没有将标准输入、标准输出和标准错误重定向(或关闭)到文件或 /dev/null,并且出于某种原因启动器(“用于并行运行多个运行级别脚本”) 进程(据我所知,它是在启动期间启动其他进程的进程)因此在我的这个脚本上被阻止。它确实启动了我的脚本,但它本身没有完成运行,并停留在进程列表中显示的阶段:
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
源代码启动器在这儿:http://svn.savannah.nongnu.org/viewvc/startpar/trunk/startpar.c?root=sysvinit&view=markup
我浏览了一下,并在 stackoverflow 上发布了一个新问题,并做了初步分析。链接位于更新我在这里添加了我的问题。
我最终使用的解决方案是这样的:
su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"
苏- 替代用户身份某些用户
-C-su 参数运行指定的命令
禁止- 运行不受挂断影响的命令。防止父进程终止子进程的情况。此处添加以防万一。但实际上在我的特定情况下没有效果。是否需要取决于环境(检查购物)
>/dev/null- 将标准输出重定向为无,基本上禁用它。
2>&1- 将标准错误(2)输出重定向到标准输出(1),后者重定向为空
&- 分离到后台,这将把标准输入也重定向到 /dev/null。
查看我的系统上运行的其他已知守护进程的文件描述符,我发现重定向到 /dev/null 是常见的事情。只有一些守护进程实际上完全关闭了 stdin、stdout、stderr。例如,可以通过以下方式实现:
su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"
从实际意义上讲,它们都是一样的,并且都是需要(任一选项)来干净地分离作为后台守护进程的进程。