From msouth at gmail.com Fri Jul 20 22:18:16 2012 From: msouth at gmail.com (Mike South) Date: Sat, 21 Jul 2012 00:18:16 -0500 Subject: [DFW.pm] introduction and a fact about exec Message-ID: 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: