sirstruck has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I have a machine running Windows XP that hosts an Apache web server. On this machine, I also have a batch file that invokes Java to run a Java application. I've authored a Perl script to change to the directory that the batch file is in and then to run it. When I double-click on the Perl file, the Java application is run within a command window. This window allows me to see all the output from the application. It also allows me to kill the application by simply closing the window.

Now, I've taken that Perl script and put it in the Apache cgi-bin directory. When I access the script from a web browser, the Java application starts as expected. But, instead of opening a command window, the application output gets printed to the browser. Is there any way to force the Perl script to launch the batch file (and, consequently, the Java application) within a command window on the server machine?

Thanks,

David

  • Comment on CGI script: How to run batch file in command window?

Replies are listed 'Best First'.
Re: CGI script: How to run batch file in command window?
by ikegami (Patriarch) on May 19, 2010 at 20:29 UTC
    Far easier and less problematic: Send the output of the java app to a file, and read the file from your desktop.
    use IPC::Open3 qw( open3 ); my $log = "..." . get_unique_str() . ".txt"; open(local *TO_CHLD, '<', 'nul') or die; open(local *FR_CHLD, '>', $log) or die; waitpid(open3('<&TO_CHLD', '>&FR_CHLD', undef, @cmd), 0);
Re: CGI script: How to run batch file in command window?
by ww (Archbishop) on May 19, 2010 at 23:11 UTC
    echoing ikegami, sort of...

    Let's see if this paraphrase is accurate:

    you have the output of the java ap rendered in a readable form in your browser, after starting the process from a browser.

    If so, why would you complicate things by sending the ap's output to a command window on the server?

    If that window is on ( the same machine on which the browser is running | a machine visible from where you started the ap ) {
        the command window option gains nothing
    } else {
        You don't want to save the output on the machine where you start the ap
    }

    If the else alternate is the case, is there a good reason? Otherwise, why not save what the browser renders?
    Is there any chance this is an XY problem?
    Or, of course, is there something I'm just not getting?

      ikegami and ww, thanks for the responses. There is no particularly urgent reason to direct the Java app's output to a command window. The reason I wanted to do it that way is because, before I wrote the Perl script, that is how I have been working with the application. That is, for the most part, I have access to the server machine. To start my Java app, I double-click the batch file. This launches a command window where I can view output and kill the app by simply closing the window. (Your guess that the console output is disposable is correct. Anything of worth is logged using logback.) I've developed the Perl script for the case where I only have remote access to the server machine. In that case, it would be nice if the Java app launched as it normally does, within a command window. That way, if someone else launches the app remotely while I'm at the server machine, I can see the output immediately and also easily kill the Java app if need be.

      From the looks of it, this is not an easy problem to solve and it sounds like I'm better off imagining a different setup, e.g. the console output goes to a file and I kill the server with either a batch file or simply by accessing the Task Manager. By the way, can't I just as easily direct the console output to a file like this?

      system('run.bat > console.log');

      Thanks,

      David

        As long as every program started by run.bat just writes to STDOUT and STDERR, you can even use a "pipe open" and read the output directly, without messing with temporary files and without fighting the race conditions that come with them:

        open my $pipe,'run.bat |' or die "Ooops: $!"; while (my $line=<$pipe>) { print $line; # <-- stupid example } close $pipe;

        Note that this example catches only STDOUT, not STDERR. If you want both in ONE stream (that may become very hard to "unmix"), use output redirection:

        open my $pipe,'run.bat 2>&1 |' or die "Ooops: $!"; # ...

        If you want only STDERR, use that, plus get rid of STDOUT (write to the null device, i.e. NUL on DOS/Win, /dev/null on Unix):

        open my $pipe,'run.bat 2>&1 >nul |' or die "Ooops: $!"; # ...

        If you want both streams separately, use IPC::Open3 or similar.

        Also note that you probably don't need the wrapping batch file, you can also start the java runtime executable directly, typically java.exe -jar jarfile.jar arg1 arg2:

        open my $pipe,'java.exe -jar jarfile.jar arg1 arg2 |' or die "Ooops: $ +!"; # ...

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)