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

My perl script currently has a system call to matlab. When Matlab runs it spits out a file that the rest of my perl script needs. Right after the system call to matlab there is a statement in perl to open the file that matlab spits out. But unfortunately the perl script jumps onto this statement before the system call is completed. It gives me an error because the system call that produces the file this statement needs to open is not been completed and so the file doesnt exist yet. How can I solve this problem? Can I make a system call from matlab to run a perl script? this way I can split my perl script. End the first one at the system call to matlab and then incoporate a system call for the rest of my perl script in my matlab code? Is that possible.. if so how? and if not .. is there any other way to go about this problem Thank you

Replies are listed 'Best First'.
Re: System call
by Tanktalus (Canon) on Feb 03, 2005 at 22:52 UTC

    You're probably running into a common problem on Windows ... which is that because the program is normally graphical, it spawns off from CMD.EXE into a background process allowing CMD.EXE to be freed up to run something else.

    Solution 1: if Matlab has an option (commandline option, perhaps) to prevent this, use it. Not really a perl solution, but we're just looking for a solution you can use in perl, right?

    Solution 2: Eliminate CMD.EXE. To do this, you need to use the array form of system rather than the single scalar method. So, rather than calling system("matlab -run matlab.input") ... try calling it as system(qw(matlab -run matlab.input)). This may not quite work - you may have to pass in a full pathname to matlab: system('c:/program files/matlab/matlab.exe', qw(-run matlab.input)). Note how I pulled the command out of the qw so that I could put a space in it - may be useful for you.

    Of course, if you don't know ahead of time where to find matlab, you're going to have to look in $ENV{PATH} (File::Spec has a good way to get this as an array that you can look through, and I'm sure there's a module out there that can look it up for you, too).

    Hope this helps

Re: System call
by blueberryCoffee (Scribe) on Feb 03, 2005 at 23:07 UTC
    just use the backtick operator to get the system output. Perl will wait untill the program stops and then return the whole output. If this program writes to a file as you say then just ignor the output and open the file.

    For example:
    my $junk = `system call here`; # now open and process the file
      this is the sturcture of my perl scrip : -frist part of my perl script -system call to matlab (this needs to produce file A which doesnt exist so far) -second part of my perl script (this opens file A) do you just want me to change the system call to my $junk = `system call here`;? will this store file A in the same directory as my perl script? and will the second part of my perl script run only after the system call is done and it has produces file A? Thank you again
        Generally that's the idea - the output of `system call here` ends up in $junk ..

        But if `system call here` is a process - like a Matlab command - that creates an output file on its own, unless it writes the same output to STDOUT, you will likely not get it back in $junk.

        You definitely have to experiment, and note that the system command acts differently in that regard to the backticks or qx//.

        You can see the difference by running these two commands...
        perl -e 'use strict; my @n = qx!/bin/netstat -a|grep LISTEN|grep -v un +ix; sleep 4!; print $_ . $/ for @n;'
        and
        perl -e 'use strict; my @n = system("/bin/netstat -a|grep LISTEN|grep + -v unix; sleep 4"); print $_ . $/ for @n;'
        update - Unless of course, you are on Windows, then netstat and sleep probably won't work..

        Notice when using system(), @n gets printed right away, and with qx// the script waits until the external commands are done..

        If you do $junk = `system call here`;.. $junk will probably contain the Matlab command's exit code.. and you can then go open the new file A.
Re: System call
by hsinclai (Deacon) on Feb 03, 2005 at 22:51 UTC
    Sounds as if you should be saving Matlab's output into some kind of data structure in your script - so what does the relevant code look like?