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

Perl Monks, I am looking for a way to launch a shell (or other interactive interface, such as MATLAB) from perl and have it sit in the background unseen, waiting for occasional commands issued from perl. The solution doesn't have to be strictly in perl. I've been trying to make it work using perl and named pipes, for instance. My environment is UNIX.

Thanks for your brain cycles,
~MB

Replies are listed 'Best First'.
Re: interacting with background shell
by Joost (Canon) on Jun 14, 2006 at 18:22 UTC
    You can do this from perl. The main "problem" will be how interactive the program is. If you only want to pass input to the program and don't care about it's output, you can use standard open():
    open CMD,"|/some/command >/dev/null" or die "Can't fork command: $!"; # ... print CMD "line of input\n"; # ... close CMD;
    If you need both to control both input and output, there's IPC::Open2 and IPC::Open3, but those require you to be very careful about deadlocks.

    Some people like the Expect module. Never used it myself, though.

      That pipe in the open command was the missing magic I needed- thanks, Joost!
      I suppose this is a case where perldoc might have helped prevent an obvious question, though. =]
Re: interacting with background shell
by liverpole (Monsignor) on Jun 14, 2006 at 18:37 UTC
    Hi GuidoFubini,

    As someone who has used the Expect module from time to time, I can highly recommend it for those cases where you want your Perl script to communicate with a process that is normally interactive only.

    It does take some getting used to, though, because you have to take into account the possible responses that the called process (in this case MATLAB) could give you back.  For example, you might have to anticipate getting back a program prompt, or certain types of output.  To that end, I've found it helps to do a lot of testing with different input sets to make sure your Perl calling program is handling every outcome robustly.

    One of the slick things about the Expect module is that it lets you use the Expect functionality without programming in Tk (which I've always preferred Perl over); sort of "best of both worlds" situation.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: interacting with background shell
by zentara (Cardinal) on Jun 14, 2006 at 20:17 UTC
    Just to amplify on what joost advised, you can "sometimes" get better results with a piped open command, if you pipe open a bash shell interpreter, then print commands to it. Like:
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; $|=1; #my $pid=open3(\*IN,\*OUT,\*ERR,'/bin/bash'); my $pid=open3(\*IN,\*OUT,0,'/bin/bash'); # set \*ERR to 0 to send STDERR to STDOUT my $cmd = 'matlab -interactive'; #send cmd to bash print IN "$cmd\n"; #getresult my $result = <OUT>; print $result;
    The reason I mention it, is that matlab(which I don't use, so this is speculation) may act funny in interactive mode, unless it is running from a shell. So if
    my $pid=open3(\*IN,\*OUT,0, '/usr/bin/matlab');
    dosn't seem to work well, try the above trick.

    Another thing I will mention, is that if you are doing huge number calculations, you may run into a problem with the 4k buffer that IPC uses on linux. In case you are curious, see what I did for running the 'bc' calculator, and getting huge output at IPC3 buffer limit problem


    I'm not really a human, but I play one on earth. flash japh
Re: interacting with background shell
by jhourcle (Prior) on Jun 14, 2006 at 18:47 UTC

    It might be worth looking into MATLAB's features. I know some other similar programs (eg, IDL), have a server mode, so that that you can start up and instance, and send commands to it.

    I found mention of a 'MATLAB server', but I have no idea if it requires a different license from the standard MATLAB.

    You might also be interested in Math::Matlab.