On Thu, Jun 19, 2003 at 07:01:32PM -0700, Jeff Westman wrote:
>--- Jeff 'japhy' Pinyan <[EMAIL PROTECTED]> wrote:
>> On Jun 19, Jeff Westman said:
>> 
>>>     1  #!/bin/perl -w
>>>     2
>>>     3  @a = qx{set};
>> 
>>> Can't exec "set": No such file or directory at ./x line 3.
>>>
>>> Yet, using qx{env} works fine.  Why?
>> 
>> Because 'set' is a shell built-in, and 'env' is a program.  Whatever 
>> shell Perl is using to run your command, it DOESN'T have a built-in 
>> called 'set' in it.
>> 
>> Why not just use the %ENV hash?
> 
> Okay, makes perfect sense (I should have known better).  As far as using
> %ENV, of course I can use that, but I was more curious as to why the qx{set}
> wasn't working.  (still, I would have thought that the builtins (or
> functions, ksh, bash) would have been checked before the $PATH.

Actually, the shell isn't involved at all.  Since there are no shell
metacharacters in the string "set", perl tries to exec "set" directly,
using the C library function execvp(), which uses $PATH.

    $ strace -f perl -e 'qx(set)' 2>&1 |grep exec
    execve("/usr/bin/perl", ["perl", "-e", "qx(set)"], [/* 22 vars */]) = 0
    [pid 10527] execve("/bin/set", ["set"], [/* 22 vars */]) = -1 ENOENT 
    [pid 10527] execve("/usr/bin/set", ["set"], [/* 22 vars */]) = -1 ENOENT
    [pid 10527] execve("/usr/X11R6/bin/set", ["set"], [/* 22 vars */]) = -1 ENOENT
    [pid 10527] execve("/opt/bin/set", ["set"], [/* 22 vars */]) = -1 ENOENT

If you add a shell metacharacter, then perl will use the shell:

    $ strace -f perl -e 'qx(set;)' 2>&1 |grep exec
    execve("/usr/bin/perl", ["perl", "-e", "qx(set;)"], [/* 22 vars */]) = 0
    [pid 10594] execve("/bin/sh", ["sh", "-c", "set;"], [/* 22 vars */]) = 0

The same thing goes for system(), which is where this subtlety
is documented.

    $ perldoc -f system

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to