in reply to CLASSPATH problem when using backticks

What you need is a way to capture the output from the java app without invoking an intermediate shell. Then your command line arguments will not get re-interpreted. A good standard module for this is IPC::Open3. Try something like this:
use IPC::Open3; sub backticks { my $pid = open3(my $wfh, my $rfh, 0, @_) or die "open3 failed: $!"; close($wfh); # assume the script needs no input my $output; while (<$rfh>) { $output .= $_ } close($rfh); $output; } my $java_output = backticks('java', '--classpath=...', ...);

Replies are listed 'Best First'.
Re^2: CLASSPATH problem when using backticks
by ikegami (Patriarch) on May 21, 2008 at 17:47 UTC

    No need for open3.

    sub backticks { open(my $pipe, '-|', @_) or return; local $/ = wantarray ? $/ : undef; <$pipe> } my $java_output = backticks('java', '--classpath=...', ...);

    Bonus: Handles context and errors just like the real thing.

      Is this available in a standard module? If not, I think it should be. The situation seems to comes up enough. I'd like to deprecate all calls to exec which invoke an intermediate shell and replace them with safer alternatives.

      Update: Banning all use of the single-argument forms of exec, system, etc. is probably too draconian. The real problem occurs when a variable is interpolated in that single argument, e.g. my $output = `command $arg`. Perhaps this is something that Perl::Critic can look for and advise that a safer way should be sought to perform the operation.

        Banning all use of the single-argument forms of exec, system, etc. is probably too draconian.

        Not really. It would just force the shell to be mentioned explicitly when it's needed. For example,

        system('sh', '-c', 'some_program >output 2>&1');

        That would hurt portability to Windows, but launching processes in Windows is so messed up already. And not just at the shell level, at the system level. All the arguments you carefully separated are assembled into a command line, cause that's the only way the system can pass args to a program.