1

我在 perl 脚本中有以下设计:

my $child_pid = fork;
if( ! $child_pid ){
    # do some stuff...
    exec( $user_specified_command );
else{
   # wait for child to exit
   waitpid( $child_pid, 0 );
}
# Continue with the script

我有兴趣在子执行时在父级中收到警报,以便我可以获得一些详细信息$user_specified_command(特别是用于lsof确定 stdout 是否被重定向到常规文件)。结果将是这样的:

my $child_pid = fork;
if( ! $child_pid ){
    # do some stuff...
    exec( $user_specified_command );
else{
   # wait until the child exec's
   wait_child_exec();

   # do some stuff...

   # wait for child to exit
   waitpid( $child_pid, 0 );
}
# Continue with the script

我可以循环和 grepps输出直到名称更改,但似乎 exec 是一个足够严重的事件,有更好的方法。

4

1 回答 1

2

一种通用的方法是在父级中创建一个由子级继承的管道,并让父级阻塞(或轮询)管道的读取端。

假设孩子有 FD_CLOEXEC 或者,更好的是,一个合适的值$^F,孩子的调用exec()将关闭管道的写入端并为父母生成一个 EOF:

# Run a command in a child process, returning to the parent only after
# the child process has called exec'd or, failing that, terminated.
#
# WARNING - this code not rigorously tested
#
sub spawn_patiently {
  my ($rd, $wr);

  return unless pipe($rd, $wr);
  # XXX This assumes $^F is less than fileno($wr)
  #     In practice, you'd want it to be less than fileno($rd), too

  my $pid = fork();
  return unless defined $pid;

  if (! $pid) {
    exec @_;
    die "exec: $!";
  }

  # parent - wait for child to exec
  close($wr);
  read($rd, my $dummy, 1);

  1;
}
于 2012-03-30T20:45:21.887 回答