in reply to Question about input pipes and sub-shells

You could use the "-|" form of open and exec your program directly:
my $pid = open(PIPE, '-|'); if (!defined($pid)) { die "fork failure: $!\n"; } elsif (!$pid) { # Child process exec 'search', $pattern; die "exec failure: $!\n"; } else { # parent ... }
This guarantees there won't be copy of the shell involved, so shell metacharacters in the search string are irrelevant.

Replies are listed 'Best First'.
Re: Re: Question about input pipes and sub-shells
by blakem (Monsignor) on Nov 15, 2001 at 00:02 UTC
    Along the same lines... here is the relevant section from open:
    If you open a pipe on the command '-', i.e., either '|-' or '-|', then there is an implicit fork done, and the return value of open is the pid of the child within the parent process, and 0 within the child process. (Use defined($pid) to determine whether the open was successful.) The filehandle behaves normally for the parent, but i/o to that filehandle is piped from/to the STDOUT/STDIN of the child process. In the child process the filehandle isn't opened--i/o happens from/to the new STDOUT or STDIN. Typically this is used like the normal piped open when you want to exercise more control over just how the pipe command gets executed, such as when you are running setuid, and don't want to have to scan shell commands for metacharacters. The following pairs are more or less equivalent:

    open(FOO, "|tr 'a-z' 'A-Z'");
    open(FOO, "|-") || exec 'tr', 'a-z', 'A-Z';

    open(FOO, "cat -n '$file'|");
    open(FOO, "-|") || exec 'cat', '-n', $file;

    See Safe Pipe Opens for more examples of this.

    -Blake