0

I'm using ActivePerl 5.12.4 on Windows 7. I have this in my script …

my $cmd = "ant -Dbuildtarget=$env -Dmodule=\"$module\" -Dproject=$project -Dnolabel=true checkout-selenium-tests";
print "cmd: $cmd\n"; 
open(F, $cmd) or die "Failed to execute: $!";
while (<F>) {
    print;
}

Sadly, my script dies at the "open" command with the failure:

Failed to execute: Invalid argument at run_single_folder.pl line 17.

I don't know what's wrong. When I print out the command that's executed, I can execute that command normally in the command window and it runs fine. How can I figure out why executing the command in the Perl script is dying when it is succeeding on the command prompt?

Kai
  • 38,985
  • 14
  • 88
  • 103
Dave
  • 8,667
  • 25
  • 72
  • 90

2 Answers2

4

You need to tell Perl it's a pipe using "|".

open(my $PIPE, "foo |")   # Get output from foo

open(my $PIPE, "| foo")   # Send input to foo

Since you don't need the shell, let's avoid it but using the multi-arg version. For one thing, it saves you from converting $env, $module and $project to shell literals (like you tried to do with $module).

my @cmd = (
   ant => (
      "-Dbuildtarget=$env",
      "-Dmodule=$module",
      "-Dproject=$project",
      "-Dnolabel=true",
      "checkout-selenium-tests",
   )
);

open(my $PIPE, '-|', @cmd) or die "Failed to execute: $!";
while (<$PIPE>) {
   print;
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
2

If you want to start a subprocess with a call to open() and capture its output you need to use a | after the command, or perl will think you want to open a file.

Matt K
  • 13,370
  • 2
  • 32
  • 51
  • 3
    Better, use the three-argument version of open: `open(F, '-|', $cmd)` – Christoffer Hammarström Sep 21 '11 at 13:59
  • 3
    Yeah, the three argument form of `open` is considered best practice. Also, using a scalar to hold your filehandle e.g. `open (my $fh, '-|', $cmd)`. See http://stackoverflow.com/questions/1479741/why-is-three-argument-open-calls-with-lexical-filehandles-a-perl-best-practice – Matt K Sep 21 '11 at 14:04
  • 1
    The list of obsolete but persistent idioms goes on and on. ;) – musiKk Sep 21 '11 at 14:09
  • 1
    @Christoffer Hammarström, You're cargo culting. Three arg offers an advantage over two args for file names, but that's not the case for pipes. Ideally, you'd use 4+ args for pipes to avoid the shell. – ikegami Sep 21 '11 at 15:40
  • Rock on. The three argument method with the '-|' worked great for me. – Dave Sep 21 '11 at 15:48