Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Create a zombie process in shell

1,305 views
Skip to first unread message

homer

unread,
Aug 7, 2011, 5:01:49 PM8/7/11
to
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)?

Thanks

James Waldby

unread,
Aug 7, 2011, 7:03:33 PM8/7/11
to

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

Stephane CHAZELAS

unread,
Aug 8, 2011, 10:22:30 AM8/8/11
to
2011-08-7, 23:01(+02), homer:
[...]

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

homer

unread,
Aug 10, 2011, 2:51:06 PM8/10/11
to
On Mon, 8 Aug 2011 14:22:30 +0000 (UTC), Stephane CHAZELAS
<stephane...@yahoo.fr> wrote:

> 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.

0 new messages