http://www.perlmonks.org?node_id=887244

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

so exec always invokes the shell?
#!/usr/bin/perl -- use strict; use warnings; my $perl = 'perl'; # $^X; my @args ; if( @ARGV ){ # no output from exec/systemx @args = ( qw! -l -e !, q!print for @ARGV!, "1 2" ); } else { # output from exec/systemx, but on 2 lines, wrong output @args = ( qw! -l -e !, q!"print for @ARGV"!, '--',"1 2" ); } warn "$perl @args \n"; warn 'system '; system $perl, @args; { use IPC::System::Simple qw' systemx '; warn 'systemx '; systemx $perl, @args; } warn 'exec '; exec $perl, @args; # bug warn " $! $^E "; __END__
$ perl junk.pl 1 perl -l -e print for @ARGV 1 2 system at junk.pl line 24. 1 2 systemx at junk.pl line 29. exec at junk.pl line 33. $
$ perl junk.pl perl -l -e "print for @ARGV" -- 1 2 system at junk.pl line 24. 1 2 systemx at junk.pl line 29. 1 2 exec at junk.pl line 33. $ 1 2
Huuuh?

Replies are listed 'Best First'.
Re: exec always invokes the shell? win32
by ELISHEVA (Prior) on Feb 09, 2011 at 19:44 UTC

    That demo looks to me like your program spawned a process that finished after your main program returned. exec doesn't spawn a shell. Rather it starts a process that runs on its own independent of your main program. To quote the Perl docs "The exec function executes a system command and never returns". This new process can finish before or after the first process. If the old process finishes first it will display the command prompt before the new process spits out its own output.

    You are seeing the "$" before the 1/2 due to a timing issue. See exec.

      You are seeing the "$" before the 1/2 due to a timing issue

      That has nothing to do with the question. Pay attention to the quotes.

      I am passing exec a list. At what point does "1 2" turn into "1" "2"? Perl does not split arguments on whitespace, that is something cmd.exe does.

        It may not exactly be that cmd.exe is being called. What you are more likely seeing is a side effect of the way programs need to pass arguments to MS-Win programs. A similar issue (parameter list mangling) was seen recently when someone ran into problems passing parameters from Java to Perl with a system call. He too was passing a list.

        The issue is this: MS-Windows programs don't actually get lists when they are called by Ms-Win. They expect to get a single string (lpCmdLine). Programs usually have some internal code that converts that string back into an array. In order to play nicely with that code, Java (and I now suspect Perl) takes your list and concatenates it into a string before passing it. The program (in this case Perl) then splits it back into arguments and viola.

        For some in depth discussion about why there just aren't any good choices in this matter, see http://bugs.sun.com/view_bug.do?bug_id=4064116. You might also want to look at these two posts on the Java/Perl thread: Re^9: Running perl from java and Re^8: Running perl from java or the thread as a whole.