Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: greps pipes and eval bad patterns



On Sun, Oct 25, 2015 at 6:02 PM, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
wrote:

> On Oct 25, 12:47pm, Ray Andrews wrote:
> }
> } test1 ()
> } {
> }      gstring=" | grep \[01;34m "
> }      tree --du -haC | grep -Ev "^[^\[]{$levels}\[*" "$gstring"
> } }
>
> One doesn't normally build up a pipeline that way, but if you must do
> so, you're on the right track with "eval" -- you just haven't applied
> enough quoting....


In addition to what Bart said I'll point out that it's usually easier and
safer to avoid the eval by using an if/else block. Getting the quoting
right when using eval can be very difficult. Especially if you don't have
direct control over the text being eval'd; e.g., if some of it is supplied
by the user; or even just built up from earlier parts of the function.

I have several functions where 99% of the time I want the output
automatically piped into my pager (e.g., /usr/bin/less). But if the output
of the function is redirected away from my tty I don't want the pager in
the pipeline. So instead of using a variable that would normally contain "|
$PAGER" and sometimes be empty (i.e., using Ray's approach) I simply spell
it out:

    if [[ -t 1 ]] ; then
      grep -h -E $case_insensitive -- "$search_for" $files | $PAGER
    else
      grep -h -E $case_insensitive -- "$search_for" $files
    fi

Yes, that introduces some redundancy. But it's far clearer and safer than
writing something like this (totally untested):

    if [[ -t 1 ]] ; then
      pager='| $PAGER'
    else
      pager=''
    fi
    eval grep -h -E $case_insensitive -- "$search_for" $files $pager

-- 
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank


Messages sorted by: Reverse Date, Date, Thread, Author