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

I need to run a program (svg2pdf) and capture the result in a scalar. I know that I can use the backtick operator to execute and capture the return value from a command, but svg2pdf accepts an input file and an output file. I need to send a scalar (output from an HTML::Template template) as the input file, and then capture the resulting PDF data to store in a database. How do I do this?

Replies are listed 'Best First'.
Re: Capturing program output
by BrowserUk (Patriarch) on Jan 14, 2011 at 07:29 UTC

    On Windows you should be able to bypass the disk file by specifying the output file as CON. Eg:

    my $pdf = qx[ svg2pdf source.svg con ];

    There is probably a pseudo tty incantation that would do the same thing on *nix.


    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.
Re: Capturing program output
by Anonymous Monk on Jan 14, 2011 at 06:20 UTC
    You don't. You send svg2pdf exactly what it expects, and input filename and an output filename; you can't circumvent this
Re: Capturing program output
by Anonyrnous Monk (Hermit) on Jan 14, 2011 at 08:47 UTC

    In theory, you could use named pipes, though I'm not sure if it's worth the trouble...

    Some programs also understand '-' as a pseudo filename representing stdin (not sure about svg2pdf) — but there's typically no equivalent placeholder for stdout. (Otherwise - if there was - you could set up bidirectional communication, e.g. with IPC::Open3.)

      you could use named pipes

      ++, but only on UNIX like operating systems. Named pipes on Windows are rather different.
Re: Capturing program output
by tmaly (Monk) on Jan 14, 2011 at 14:25 UTC

    use pipes as others have suggested or the oo wrapper IO::Pipe and just write to the pipe in an anonymous sub that is passed into the template process method.

      The problem is not so much setting up the pipes on the Perl side, but rather getting the other side (svg2pdf in this case) to communicate via the pipes, if it expects to do its IO solely via named files instead of stdin/stdout — as svg2pdf apparently does, according to the OP.

      IO::Pipe won't really help in this regard. as it sets up normal anonymous pipes, and those can only be used if the subprocess on the other end cooperates.