perl -e 'if(fork){print "there is a zombie for 30 seconds\n"; sleep 30}'
For exploration purposes, I tried to reproduce the same behavior in the
shell, with this code:
#!/bin/bash
exit &
echo "There is a zombie for 30 seconds"
sleep 30
wait
(where "exit &" is supposed to create the child process)
But the above script does not create any zombie. Is it possible? Am I doing
something wrong (most likely)?
Thanks
The bash man page says "If a command is terminated by the control
operator &, the shell executes the command in the background in a
subshell. The shell does not wait for the command to finish, and
the return status is 0." Where the man page says "does not wait",
it means "does not block" rather than "does not waitpid()". After
all, later in the man page we read, "The shell learns immediately
whenever a job changes state."
You can instrument your test script a little better by adding
the following lines after exit and before echo:
BP=$!
echo "$$ started $BP"
sleep 1
echo ps $BP says:
ps $BP
--
jiw
The shell will take care of its children internally by
installing handlers on SIGCHLD. You could use:
(: & exec sleep 30) &
echo there is a zombie for 30 seconds
wait
Here, we're replacing the shell process that is the parent of
the one executing ":" with "sleep" that won't catch the process
termination.
In shells where "sleep" is built-in, you may need:
(: & exec /bin/sleep 30) &
echo there is a zombie for 30 seconds
wait
There's also a potential for ":" to terminate (and the parent
shell to catch it) before "exec" is run, in which case, you may
need:
(sleep 1 & exec /bin/sleep 30) &
sleep 1
echo there is a zombie for 29 seconds
wait
--
Stephane
> 2011-08-7, 23:01(+02), homer:
> > The following Perl code creates a zombie for 30 seconds:
> >
> > perl -e 'if(fork){print "there is a zombie for 30 seconds\n"; sleep 30}'
> >
> > For exploration purposes, I tried to reproduce the same behavior in the
> > shell, with this code:
> >
> > #!/bin/bash
> >
> > exit &
> > echo "There is a zombie for 30 seconds"
> > sleep 30
> > wait
> >
> >
> > (where "exit &" is supposed to create the child process)
> > But the above script does not create any zombie. Is it possible? Am I
> > doing something wrong (most likely)?
> [...]
>
> The shell will take care of its children internally by
> installing handlers on SIGCHLD.
Thanks! Is this documented? I'm using bash.
> You could use:
>
> (: & exec sleep 30) &
> echo there is a zombie for 30 seconds
> wait
>
> Here, we're replacing the shell process that is the parent of
> the one executing ":" with "sleep" that won't catch the process
> termination.
Right. Would also installing an explicit null handler for SIGCHLD prevent
the shell for using its built-in handler? For example, like
trap ':' SIGCHLD
: &
echo "There is a zombie for 30 seconds"
sleep 30
This doesn't seem to work.