Проверка, исполняется ли разветвленный ребенок в Perl - PullRequest
1 голос
/ 30 марта 2012

У меня есть следующий дизайн в 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

Я мог бы зацикливать и выводить grep ps до тех пор, пока имя не изменится, но кажется, что exec - достаточно серьезное событие, и есть лучший способ.

1 Ответ

2 голосов
/ 31 марта 2012

Один общий подход к этому - создать канал в родительском объекте, который наследуется дочерним элементом, и иметь родительский блок (или опрос) конца чтения канала.

Предполагается, что дочерний элемент имеет 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;
}
...