[DFW.pm] introduction and a fact about exec

Mike South msouth at gmail.com
Fri Jul 20 22:18:16 PDT 2012


Hi,

I'm Mike South, I live in McKinney and I telecommute for a company that's
sort of based in Boston but actually headquartered in San Mateo.  I'm a
long time perl developer, currently working in the operations group of a
company that I had formerly done development for.  I'm doing a lot more
scripting now (as opposed to application development) and learning a lot
about infrastructure that I formerly only learned as much as I needed to
solve whatever and get back to working on the application.

I was writing a diagnostic script the other day and I learned something
that may be common knowledge but I thought I would share.

The code I was writing, which I will state at the outset should probably
have used File::Tail from CPAN, sent a signal to a process and then watched
a log waiting for a response to the signal to show up there.

There is not really a good reason to do it the way I did--I was just doing
a straightforward implementation in script form of what I had been doing
manually.

So, the manual process is like this:  kill -USR2 [process id].  Then tail
-f ~/logs/error_log and wait for a response to show up there.  If it
doesn't show a response after a while, control-c that tail and go do
something else, if it does show a response, copy that and paste it into a
file.

So, in the script, I sent the kill signal, then fork()ed, and in the child
I used exec to start a tail -f redirected to an output file.

In the parent I looped for 60 tries (sleeping one second each time) seeing
if there was anything in the output file (anything other than the few lines
tail -f starts with by default, that is).

When I was done, either by giving up after 60 seconds or by seeing the
output I was looking for, I wanted to be able to kill the tail -f.  My hope
was that, by using exec (which replaces the running process with one doing
whatever you told exec to do), the pid of the exec'd process would be the
same as the pid I already knew from the fork call, so I would know what to
kill.

That worked fine, several times.  But then one time, after running the
script, when I went to log out it cleared the screen and just hung there.
 Turned out that the tail -f process was still running. I checked the pid
and it was one more than the child pid.  It seems that when you pass exec a
string with shell metacharacters in it, (remember my tail -f was redirected
to a file), exec will run a shell to parse those or something, and that
ends up being a new process.

If you don't need the string to be interpreted by the shell, you can just
pass each element of your command as a list (perldoc -f exec shows you that
there are two ways to call it), and that seems, from other reports at
least, to keep it from creating a new process.  But I needed shell
interpretation for what I was doing so that didn't help me.

In a perlmonks thread I found while searching about this, one answerer
recommended killing everything in the process group (except the parent, and
then the parent can exit).  This is easy to do (lifted straight from the
thread, except I added a missing semicolon):

        my $pgrp_id=getpgrp(0); # gets the process group id of
                                # the current process

        { # scoping is important!  Otherwise
          # that signal will always be ignored
          # by the parent, which is probably bad.
          # I picked SIGINT, you might prefer something
          # else.

            local $SIG{'INT'}='IGNORE';
            kill 2, -$pgrp_id; # - means it's a group id.
        }
        warn "sent a sig int to the process group, you should ' ps auxww
|grep tail ' to make sure that worked...\n";

There are many things that can be done better, like using IO::Select, or
just plain seeking and reading on the file handle, etc, and when I looked
just now I realized that someone else must have run into a need like this
before, because tail has a command line argument that says "quit after
process X is no longer active", which is exactly what I needed, and could
even have just called it with system if I'd known that.

But I thought the information was interesting, and figured I would
introduce myself and share.

mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/dfw-pm/attachments/20120721/b7645cf6/attachment.html>


More information about the Dfw-pm mailing list