Re: Non-shell-invoking system/exec and qx//
by pc88mxer (Vicar) on Jun 18, 2008 at 14:32 UTC
|
sub backticks {
open(my $pipe, '-|', @_)
or return;
local $/ = wantarray ? $/ : undef;
<$pipe>
}
Note that a shell could still get invoked if @_ == 1 and the first element contains shell metacharacters. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
backticks('ls foo'); # Run "ls" with argument "foo"
backticks('ls foo', '--'); # Run "ls foo" with argument "--"
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
Re: Non-shell-invoking system/exec and qx//
by Fletch (Bishop) on Jun 18, 2008 at 14:15 UTC
|
Yup. qx// is syntactic sugar for the common case; if you want custom you've got to roll your own (or maybe use IPC::Run).
The cake is a lie.
The cake is a lie.
The cake is a lie.
| [reply] [Watch: Dir/Any] [d/l] |
Re: Non-shell-invoking system/exec and qx//
by ikegami (Patriarch) on Jun 18, 2008 at 14:33 UTC
|
sub backticks {
open(my $pipe, '-|', @_)
or return;
local $/ = wantarray ? $/ : undef;
<$pipe>
}
Update: LOL! pc88mxer beat me to posting my own code! | [reply] [Watch: Dir/Any] [d/l] |
Re: Non-shell-invoking system/exec and qx//
by brian_d_foy (Abbot) on Jun 18, 2008 at 15:26 UTC
|
| [reply] [Watch: Dir/Any] |
|
Erm, if you pass a list they call execvp(3) directly rather than starting up a shell. If there's one argument but it doesn't have anything more exotic than whitespace it's split and passed to execvp rather than run through a shell. See the exec and system entries in perlfunc; or look under the hood at pp_system in pp_sys.c and Perl_do_exec3 in doio.c.
Update: this is only on fork-available /bin/sh-having OSen I believe; I can't speak to what unnatural machinations are done elsewhere as my eyes started to glaze over with some of the #ifdef'ing going on.
The cake is a lie.
The cake is a lie.
The cake is a lie.
| [reply] [Watch: Dir/Any] |
|
$ strace -fq -eexecve perl -e 'system "/bin/echo", "foo"'
execve("/usr/local/bin/perl", ["perl", "-e", "system \"/bin/echo\", \"
+foo\""], [/* 71 vars */]) = 0
[pid 27279] execve("/bin/echo", ["/bin/echo", "foo"], [/* 71 vars */])
+ = 0
So, no shell involved...
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
|
$ perl -e'system "ps -opid,ppid,cmd 2>/dev/null"'
PID PPID CMD
11096 7077 -bash
5166 11096 perl -esystem "ps -opid,ppid,cmd 2>/dev/null"
13220 5166 sh -c ps -opid,ppid,cmd 2>/dev/null
19387 13220 ps -opid,ppid,cmd
$ perl -e'system "ps -opid,ppid,cmd"'
PID PPID CMD
11096 7077 -bash
13513 11096 perl -esystem "ps -opid,ppid,cmd"
26826 13513 ps -opid,ppid,cmd
| [reply] [Watch: Dir/Any] [d/l] [select] |
Use IPC::System::Simple for non-shell invoking system/exec/qx
by pjf (Curate) on Jun 23, 2008 at 02:42 UTC
|
I believe that IPC::System::Simple is exactly what you're after. It provides a function called capture() that works just like backticks in how you'd call it, but never invokes the shell when called with multiple arguments.
It has the advantages of running on both Unix and Windows, provides an easy way to get access to the exit value without manually unpacking $?, throws nice error strings on failure, is pure perl, and has no dependencies.
Under Windows it has the added advantage of providing access to the full 32-bit return value, and avoids the bugs in Perl's core which can result in the shell being invoked anyway or potentially running the command twice.
Note: I have some personal bias, as I'm the author of the module. ;)
All the best,
| [reply] [Watch: Dir/Any] |
|
The author added capturex which is guaranteed not to call the shell, even if no arguments are provided.
| [reply] [Watch: Dir/Any] |
Re: Non-shell-invoking system/exec and qx//
by repellent (Priest) on Jul 18, 2008 at 01:04 UTC
|
I wrote exe() and bg() for that purpose because I felt that IPC::* syntaxes were non-intuitive, IMHO.
Pipe processes and Perl subroutines together
Internally, both functions perform safe forking methods to ensure no child zombies.
Example to sort & number the list of /tmp files:
use Exe;
my @pids = &{
exe qw(ls /tmp),
exe qw(sort -n),
exe qw(cat -n),
};
| [reply] [Watch: Dir/Any] [d/l] [select] |