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]