Operating System - HP-UX
1826290 Members
4520 Online
109692 Solutions
New Discussion

Re: system() and metachar processing in Perl

 
SOLVED
Go to solution
Leslie Chaim
Regular Advisor

system() and metachar processing in Perl

Hi,

I am trying to use the system() function to call a process.

This works:
system ("java root/MainApp " . join " ", @args);
After a lot of sweating, I figured out I must do this BEFORE:

map { s/\$/\\\$/ } @args;

That is because some of the args has '$' and my MainApp did not work;)

What I really wanted was to use the version of system where perl will bypass any Shell processing, but I cannot get it.

I tried this:
system "java", " root/MainApp ", join " ", @args;
and this:
system "/opt/java1.4/bin" "java", " root/MainApp ", join " ", @args;
and even this:
system {$ENV{PATH}} "java", " root/MainApp ", join " ", @args;

I can't get it to work. Maybe I do not understand what the PATHNAME means in the docs.

Thanks in advance,
Leslie
If life serves you lemons, make lemonade
8 REPLIES 8
Vincent Stedema
Esteemed Contributor

Re: system() and metachar processing in Perl

Hi,

Can you try this:

$ENV{PATH}.=':/opt/java1.4/bin';
system('java','root/MainApp',@args);

This adds the location of the 'java' binary to your environment and then executes the app. If this doesn't work, pls post the error message.

Regards,

Vincent
Leslie Chaim
Regular Advisor

Re: system() and metachar processing in Perl

I did set the $ENV{PATH}

The error message is:

Can't exec "java root/MainApp ": No such file or directory at ./wrapApp line 103.
If life serves you lemons, make lemonade
Vincent Stedema
Esteemed Contributor
Solution

Re: system() and metachar processing in Perl

Remove the leading space from " root/MainApp" and try again. Seems "system" doesn't like the extra space.

Compare

# perl -wle "system('ls','*')"
and
# perl -wle "system('ls',' *')"

The second one generates an error on my system.

Hope this fixes it...

Regards,

Vincent
Leslie Chaim
Regular Advisor

Re: system() and metachar processing in Perl

Thanks Vincent; it worked!
Gee, since when is Perl so picky?!
If life serves you lemons, make lemonade
Ralph Grothe
Honored Contributor

Re: system() and metachar processing in Perl

Leslie,

though it worked you should have a look at the POD of system():

perldoc -f system

There it clearly says that the shell will be invoked whenever you give system a single argument (i.e. one command line string) or a list with only one entry (i.e. array where @array == 1).

Thus you completely avoid the shell by calling system with a list of arguments (which you should almost always do).
So forget about the join() in your argument list.

Madness, thy name is system administration
H.Merijn Brand (procura
Honored Contributor

Re: system() and metachar processing in Perl

As Ralph already quoted from the docs, you can eliminate the shell interface by calling 'system' with a list. If you do so, all arguments are passed litterally, so spaces count.

If calling system with one (string) argument, spaces are the separators for the arguments as in the shell

system "java @args";

would already do what you need, because arrays are expanded when used in interpolating strings. The elements are `join'ed by the value of $", which defaults to space.
Enjoy, Have FUN! H.Merijn
Leslie Chaim
Regular Advisor

Re: system() and metachar processing in Perl

Thanks Ralph and Procura for you input.

Just to quote part of my original question:
"What I really wanted was to use the version of system where perl will bypass any Shell processing, but I cannot get it."

I was trying to send a LIST to system(), I guess the join() thing was just part of the cut 'n' paste when it DID work;)

Anyway, did any of you ever used the PATHNAME feature of system() or exec()? The docs are a bit terse on the PATHNAME feature.

Thanks,
If life serves you lemons, make lemonade
H.Merijn Brand (procura
Honored Contributor

Re: system() and metachar processing in Perl

From 'perldoc -f system':

--8<---
system LIST
system PROGRAM LIST
Does exactly the same thing as "exec LIST", except that a fork
is done first, and the parent process waits for the child
process to complete. Note that argument processing varies
depending on the number of arguments. If there is more than
one argument in LIST, or if LIST is an array with more than
one value, starts the program given by the first element of
the list with arguments given by the rest of the list. If
there is only one scalar argument, the argument is checked for
shell metacharacters, and if there are any, the entire
argument is passed to the system's command shell for parsing
(this is "/bin/sh -c" on Unix platforms, but varies on other
platforms). If there are no shell metacharacters in the
argument, it is split into words and passed directly to
"execvp", which is more efficient.

-->8---

So if you want to be sure that you don't get shell interference, use the list version, for which you are sure that there are no metacharacters. rewrite arguments that you *do* want expanded, to be expanded /before/ they are passed to system.

The output of

system "ls *";

should be the same, but slower, as:

system "ls", glob "*";


Enjoy, have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn