So, if I were to use pipes, with a timeout, would it look something like
this?

#!/usr/bin/perl

use warnings;
use strict;

$SIG{ALRM} = sub { die "timeout\n" };

alarm(7);

my $pid = open(my $HANDLE,
         "echo \"A\"; sleep 3;"
        ."echo \"B\"; sleep 3;"
        ."echo \"C\"; sleep 3;"
        ."echo \"D\"; sleep 3;"
        ."echo \"E\"; sleep 3;"
        ."|") or die "failed to open";

while(<$HANDLE>){
        print "line is $_";
}


???

When I run this, it prints out A, then three seconds later, B,
then three seconds later "C", then it prints "timeout" and dies.

I do a ps -ef and don't see any process hanging around.

So, I think this has all the functionality I need.
I can capture the text output and put it in a file
as well as print it out immediately for the user to see,
and then I can do a timeout and there aren't any processes
hanging aroudn that I see.

But since this is a very weird way of doing things for me,
I thought I'd check in before I rewrite the script and
discover I did it all wrong. Again.

Will this work cleanly and reliably?

Greg






> Ah-ha.
>
> I'm not entirely crazy, just extremely forgetful.
> I knew I had done a script like this a couple years ago
> and I knew it used backticks and I knew it had a timeout feature.
>
> The part I forgot was it used Tk::ExecuteCommand to
> manage the process. It also shows the output of the
> simulation. and it provides the user with an interactive
> way to kill the simulation in the middle.
>
> This script seems to timeout properly and kill the underlying
> process so as to not leave any zombies around:
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
>
> use Tk;
> use Tk::ExecuteCommand;
>
> my $oscmd="echo \"hello\"; sleep 30000; echo \"world\";";
>
> my $top=new MainWindow;
> my $ec = $top->ExecuteCommand()->grid(-row=>1,-column=>1);
>
> $SIG{ALRM} = sub { $ec->kill_command; };
> alarm(10);
>
> $ec->configure(-command => $oscmd);
> $ec->execute_command;
> $ec->update;
>
>
>
>
> I need to add gui support anyway, so I'll just tweak
> my script to tee its output during backtick commands
> and use Tk::ExecuteCommand to handle the OS command.
> There's still the problem of buffering, but I'll deal
> with that later.
>
> And apparently I need to read up on pipes in case
> this bites me again and I can't use a gui.
>
> Greg
>
>
>
>
>> Don't do that.
>>
>> In general, you're going to run into a whole mess of problems with the
>> kind
>> of thing you want to do, and your best is to control everything and
>> avoid
>> the shell. Pipe opens, as Uri suggested, are the way to go, unless you
>> need
>> bi-/tri-directional support in which case there are
>> IPC::Open[23]/IPC::Run.
>>
>> But often you can get away, from perlipc:
>>
>>        On most Unix platforms, the "CHLD" (sometimes also known as
>> "CLD")
>> sig-
>>        nal has special behavior with respect to a value of 'IGNORE'.
>> Setting
>>        $SIG{CHLD} to 'IGNORE' on such a platform has the effect of not
>> creat-
>>        ing zombie processes when the parent process fails to "wait()" on
>> its
>>        child processes (i.e. child processes are automatically reaped).
>> Call-
>>        ing "wait()" with $SIG{CHLD} set to 'IGNORE' usually returns "-1"
>> on
>>        such platforms.
>>
>
>
> --
>
>
>


-- 



_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to