为什么我用 Perl 的 system() 启动的进程不是子进程?
Perl的system()启动一个进程,但破坏了父/子关系?
test.pl:test.sh
use POSIX;
system("./test.sh &");
my $pid = `ps -C test.sh -o pid=`;
print "pid: -$pid-\n";
waitpid($pid, 0);
:
while true
do
sleep 1
done
当我运行test.pl时,它找到并打印test.sh的正确pid。 但 waitpid() 返回 -1 并且 test.pl 退出。 test.pl存在后,test.sh仍在运行。
看起来 test.sh 不是 test.pl 的子项,这会破坏 waitpid()。 为什么会发生这种情况以及如何使 system() 表现出来? 这是因为 Perl 自动清除子进程吗? 如果是,我该如何解决显式等待孩子的一般任务?
更新:
下面的答案建议使用 fork/exec。 最初的问题是这样的:
从 Perl 脚本中运行启动服务的命令行实用程序。 该实用程序退出,但服务保留。
一段时间后,找到该服务的 pid 并等待它。
fork/exec 并没有解决这个问题,尽管它澄清了这个问题。
Perl's system() starts a process, but breaks the parent/child relationship?
test.pl:
use POSIX;
system("./test.sh &");
my $pid = `ps -C test.sh -o pid=`;
print "pid: -$pid-\n";
waitpid($pid, 0);
test.sh:
while true
do
sleep 1
done
When I run test.pl, it finds and prints a correct pid of test.sh. But waitpid() returns -1 and test.pl exits. After test.pl exist, test.sh is still running.
It looks like test.sh is not a child of test.pl, which breaks waitpid(). Why does this happen and how to make system() behave? Is that because Perl clears children automatically? If yes, how can I solve a general task of waiting on a child explicitly?
Update:
answers below suggest using fork/exec. The initial problem is this:
from a Perl script, run a command-line utility that starts a service. The utility exits but the service stays.
after some time, find that service's pid and wait on it.
fork/exec doesn't solve this, although it clears up the question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一般来说,如果你不想 Perl 帮忙,你应该手动 fork 和 exec
你出去。 很难确定你到底在做什么,但我
认为你想要这个:
就个人而言,我更喜欢让 AnyEvent 照顾:
或者,更一般地说: http ://github.com/jrockway/anyevent-subprocess/tree/master
In general, you should manually fork and exec if you don't want Perl to help
you out. It's hard to determine exactly what you are doing, but I
think you want this:
Personally, I prefer to let AnyEvent babysit:
Or, more generally: http://github.com/jrockway/anyevent-subprocess/tree/master
为了进一步解释 Liudvikas 的答案 -
在分叉并运行 test.sh 脚本后,/bin/sh shell(Perl 系统调用的子级)退出,因此您从 waitpid() 获得 -1 返回值。
To further explain Liudvikas' answer -
After fork'ing and running the test.sh script the /bin/sh shell, which was the child of the Perl system call, exits and so you get a -1 return value from waitpid().
test.sh 进程不是您的子进程。
system()
分叉了一个 shell(这是你的子 shell),该 shell 分叉了一个运行 test.sh 程序的子 shell。 你孩子的外壳退出了。The test.sh process is not your child process. The
system()
forked a shell (which is your child), that shell forked a child that ran the test.sh program. The shell that was your child exited.您可能想要做的是这样的:
尽管由于 shell 脚本处于无限循环中,所以它将永远等待。
What you probably want to do is something like this:
Though since the shell script is in an infinite loop, it will wait forever.