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

I'm wondering if anyone knows of an easy way to use the backticks without invoking the shell, as in a multi-argument system command. The arguments I'll be passing in may include spaces as well as both kinds of quotes, so I don't want to go through the effort of sanitizing them before passing to a shell command.

I know I can do it with the pipe-fork-exec-read series of operations, but I'm hoping for a simpler trick.

Replies are listed 'Best First'.
Re: Backticks without shell
by Zaxo (Archbishop) on Jan 21, 2004 at 03:23 UTC

    You can use the list syntax for piped open if your perl is recent enough. This works in my 5.8.x,

    $ perl -e'open my $fh, "-|", "ls", "-l", glob("READ*") or die $!; prin +t <$fh>' -rw-rw-r-- 1 Zaxo Zaxo 1510 Jan 15 1999 README -rw-rw-r-- 1 Zaxo Zaxo 251 Jan 15 1999 README_FIRST -rw-rw-r-- 1 Zaxo Zaxo 245 Jan 15 1999 README_FIRST.~ +1~ $
    while,
    $ perl -e'open my $fh, "-|", "ls", "-l", "READ*" or die $!; print <$fh +>' ls: READ*: No such file or directory $
    proving that the shell is truly bypassed.

    After Compline,
    Zaxo

      Thanks! I'll probably upgrade just to use this.

      Does anyone know why backticks are an operator in the first place? It seems like the syntax is broken compared with system, because it's a loss of functionality. Wouldn't having stdout( ... ) as a complement to system( ... ) make more sense?

        My guess (No informed ideas here!) that they're a legacy feature from trying to support bash scripters and their backticks as well as it's just a quick simple and above all, lazy way to get the output of a command.
        my $data = `cmd`;
        Is vastly preferable to
        open FH,'cmd |'; my $data; $data.=$_ while(<FH>);
        (or something of that nature).
Re: Backticks without shell
by Fletch (Bishop) on Jan 21, 2004 at 03:13 UTC

    Not as simple as qx//, but there's always IPC::Open2 or IPC::Run, either of which will at least hide some of the pipe-fork-exec leaving you to just read.