好的,这是一个长的,振作起来!:)
最近我尝试在启动期间启动一个用 bash 编写的看门狗脚本。因此,我在rc.local中添加了一行,其中包含以下内容:
su someuser -c "/home/someuser/watchdog.sh &"
watchdog.sh 看起来像这样:
#!/bin/bash
until /home/someuser/eventMonitoring.py
do
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
现在,我的脚本 (watchdog.sh) 启动并成功分离,因为它的 PPID 也是 1。然后我的任务是找出该进程是什么。Startpar 是sysvinit引导系统 ( http://savannah.nongnu.org/projects/sysvinit ) 的一部分。我目前正在使用该系统的 Debian Wheezy 7.4.0。现在man startpar
说:
startpar is used to run multiple run-level scripts in parallel.
通过反复试验的方法,我基本上弄清楚了如何在启动期间正确启动我的脚本,而不是让startpar挂起。进程的所有文件描述符都需要重定向到文件或/dev/null或一起关闭。当您考虑时,这是一件理性的事情。我终于这样做了:
su someuser -c "some_script.sh >/dev/null 2>&1 &"
这解决了这个问题。但仍然让我想知道为什么会这样。为什么startpar 的行为如此。它是一个错误还是一个功能。
所以我深入研究了代码(http://svn.savannah.nongnu.org/viewvc/startpar/trunk/startpar.c?root=sysvinit&view=markup)并从头到尾开始:
首先,我找到了startpar -f -- rc.local调用的位置:
第 741 行:
execlp(myname, myname, "-f", "--", p->name, NULL);
好的,这实际上将启动一个新的startpar进程,它将替换当前正在运行的实例。它基本上是对自身的递归调用。让我们看看-f参数的作用:
第 866 行:
case 'f':
forw = 1;
break;
好的,让我们看看将forw变量设置为1的作用......
第 900 行:
if (forw)
do_forward();
最后让我们看看这个函数是怎么回事:
第 615 行:
void do_forward(void)
{
char buf[4096], *b;
ssize_t r, rr;
setsid();
while ((r = read(0, buf, sizeof(buf))))
{
if (r < 0)
{
if (errno == EINTR)
continue;
#if defined(DEBUG) && (DEBUG > 0)
perror("\n\rstartpar: forward read");
#endif
break;
}
b = buf;
while (r > 0)
{
rr = write(1, b, r);
if (rr < 0)
{
if (errno == EINTR)
continue;
perror("\n\rstartpar: forward write");
rr = r;
}
r -= rr;
b += rr;
}
}
_exit(0);
}
据我了解。这会将来自文件描述符 0 的所有内容重定向到文件描述符 1。现在让我们看看真正链接到这些文件描述符的内容:
root@server:~# ls -al /proc/3048/fd
total 0
dr-x------ 2 root root 0 Apr 2 21:13 .
dr-xr-xr-x 8 root root 0 Apr 2 21:13 ..
lrwx------ 1 root root 64 Apr 2 21:13 0 -> /dev/ptmx
lrwx------ 1 root root 64 Apr 2 21:13 1 -> /dev/console
lrwx------ 1 root root 64 Apr 2 21:13 2 -> /dev/console
嗯很有趣......所以 ptmx 是根据人的:
The file /dev/ptmx is a character file with major number 5
and minor number 2, usually of mode 0666 and owner.group of root.root.
It is used to create a pseudoterminal master and slave pair.
和控制台:
The current console is also addressed by
/dev/console or /dev/tty0, the character device with major number 4
and minor number 0.
那时我来这里是为了stackoverflow。现在,有人能告诉我这里发生了什么吗?我做对了吗,那个 startpar 处于不断将ptmx的任何内容重定向到控制台的阶段?为什么这样做?为什么是 ptmx?这是一个错误吗?