in reply to Re: Run and Stop another program in perl
in thread Run and Stop another program in perl

Thank you all for replying.
I try it and still does not work. when perl execute line my $pid = open CMD, 'program.exe |' or die $!;. program.exe will run forever and my perl script hang. It will not get to the next line, so it can't capture the output. Also it will not get to the line kill 9, $pid.

I try using fork too, but the same thing happen.
Any other suggestion?.
  • Comment on Re^2: Run and Stop another program in perl

Replies are listed 'Best First'.
Re^3: Run and Stop another program in perl
by BrowserUk (Patriarch) on Aug 21, 2010 at 17:22 UTC
    when perl execute line my $pid = open CMD, 'program.exe |' or die $!;. program.exe will run forever and my perl script hang.

    The only way I'm aware of that can happen is if the program produces output without any newlines.

    E.g: This (with -l so print adds newlines), returns control to the calling program immediately:

    $pid = open CMD, '-|', q[perl.exe -le"print ++$i while sleep 1"] or di +e $!;;

    But this (no newlines) won't return control to the caller until it fills and flushes the 4k buffer on STDOUT. Which given it only produces just a few characters every second, will take a long time:

    $pid = open CMD, '-|', q[perl.exe -e"print ++$i while sleep 1"] or die + $!;;

    If the program in question is buffering its output, is not adding newlines, and doesn't produce enough to fill the buffer, it will never return control to the caller.

    In that case, you're pretty much screwed unless you can recompile the program.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      After reading BrowserUK's last post on this, I've got one really crazy "out of the box" idea. I'm sure that there will be some who will consider this idea to be ugly and I could not disagree. Also, it's not a purely Perl solution.

      Ok, here's the crazy (stupid???) idea of mine. First, it sounds like your running on Windows, which is the basis for my idea. One good source of line command utilities for the Windows environment is the Sysinternals suite, which is available for free from Microsoft. In this case, you'll be interested in the pskill tool, which allows you to kill a process by name from a line command (i.e. the equivalent of killing a process via task manager).

      Here's the outline of what I'd try if I were in your place.

      • Download the pskill tool. (The first time you run it, there will be a pop window about the EULA. That just happens on the first time you run it.)
      • In your Perl script, modify it to use threads.
      • Start one thread to launch your program.exe such that STDERR is piped to STDOUT and STDOUT is piped to a file. From a command prompt, the syntax of that piping would be something like program.exe >log.txt 2>&1. (Can't remember the exact syntax.)
      • Start another thread that does uses sleep to wait X amount of time and the launch the pskill command to kill your program.exe (pskill program.exe).

      It may be an ugly solution, but it just might work. Also, it won't directly capture the output of your program.exe in Perl. Perhaps someone else might have a better Perl-based idea, but this is the best idea that I could come up with based on my knowledge of Perl.

      Good luck with your efforts.