grep -E -F

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

grep -E -F

Jan Stary
Apparently, grep can be called with both -E and -F:

  $ printf "foo\nbar\n" | grep -EF '(foo|bar)'
  $ printf "foo\nbar\n" | grep -FE '(foo|bar)'
  foo
  bar

and the same happens with egrep and fgrep. Indeed,

        case 'E':
                Fflag = 0;
                Eflag = 1;
                break;
        case 'F':
                Eflag = 0;
                Fflag = 1;
                break;

Should grep (or egrep or fgrep) protest
if both -E and -F (or -F or -E, respectively)
are specified? (IMHO not, but anyway?)

        Jan

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: grep -E -F

Philip Guenther-2
On Wed, Mar 15, 2017 at 12:17 PM, Jan Stary <[hidden email]> wrote:
> Apparently, grep can be called with both -E and -F:
>
>   $ printf "foo\nbar\n" | grep -EF '(foo|bar)'
>   $ printf "foo\nbar\n" | grep -FE '(foo|bar)'
>   foo
>   bar
>
> and the same happens with egrep and fgrep. Indeed,
..
> Should grep (or egrep or fgrep) protest
> if both -E and -F (or -F or -E, respectively)
> are specified? (IMHO not, but anyway?)

Seems unnecessary.

Standardese: POSIX doesn't specify that they are exclusive options or
that they override each other, so the behavior when they are used
together is simply undefined by the standard...which makes any
behavior, including using the last, legal.


Philip Guenther

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: grep -E -F

Ingo Schwarze
In reply to this post by Jan Stary
Hi Jan,

Jan Stary wrote on Wed, Mar 15, 2017 at 08:17:39PM +0100:

> Apparently, grep can be called with both -E and -F:
>
>   $ printf "foo\nbar\n" | grep -EF '(foo|bar)'
>   $ printf "foo\nbar\n" | grep -FE '(foo|bar)'
>   foo
>   bar
>
> and the same happens with egrep and fgrep. Indeed,
>
> case 'E':
> Fflag = 0;
> Eflag = 1;
> break;
> case 'F':
> Eflag = 0;
> Fflag = 1;
> break;

What you describe is a POSIX violation:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html

> Should grep (or egrep or fgrep) protest
> if both -E and -F (or -F or -E, respectively)
> are specified?

Yes, that is what POSIX requires.  It must error out.

And indeed, the following do error out on -EF and -FE:

 * GNU grep
 * DragonFly BSD (uses GNU grep)
 * illumos (in both versions: in libcmd and in grep_xpg4)
 * Solaris 11   /usr/xpg4/bin/grep
 * Solaris 9    /usr/xpg4/bin/grep

However, the following silently allow the last one to win:

 * OpenBSD
 * FreeBSD
 * NetBSD

The NetBSD implementation was copied from FreeBSD in 2011.
The FreeBSD implementation was copied from OpenBSD in 2010.
The OpenBSD implementation was written from scratch
by Carson Harding in 2000 or 2001.

So it looks like this is our Very Own Bug, and it has used
some opportunities to multiply.

> (IMHO not, but anyway?)

This should probably be fixed, but so shortly before release
is not a good time - the fallout might be entertaining...

Yours,
  Ingo

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: grep -E -F

Ingo Schwarze
In reply to this post by Philip Guenther-2
Hi Philip,

oops, our mails crossed.

> Standardese: POSIX doesn't specify that they are exclusive options

It does:

  http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html

  section 12.1, clause 8

> or that they override each other,

True, so they *do not* override each other.

> so the behavior when they are used together is simply undefined
> by the standard...

Not true, section 12.2, guideline 11.

> which makes any behavior, including using the last, legal.

No, but as i said, i doubt that now is the right time to fix it.

Yours,
  Ingo

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: grep -E -F

Ted Unangst-6
Ingo Schwarze wrote:

> Hi Philip,
>
> oops, our mails crossed.
>
> > Standardese: POSIX doesn't specify that they are exclusive options
>
> It does:
>
>   http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
>
>   section 12.1, clause 8

That also says:

        The use of conflicting mutually-exclusive arguments produces undefined
        results, unless a utility description specifies otherwise.

In that paragraph, "application" refers to the thing invoking the utility. So
a conforming script/user/etc is prohibited from calling grep -E -F.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: grep -E -F

Ingo Schwarze
Hi Ted,

Ted Unangst wrote on Wed, Mar 15, 2017 at 05:26:40PM -0400:
> Ingo Schwarze wrote:
>> Philip Guenther wrote:

>>> Standardese: POSIX doesn't specify that they are exclusive options

>> It does:
>>
>>   http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
>>
>>   section 12.1, clause 8

> That also says:
>
> The use of conflicting mutually-exclusive arguments produces undefined
> results, unless a utility description specifies otherwise.
>
> In that paragraph, "application" refers to the thing invoking the utility. So
> a conforming script/user/etc is prohibited from calling grep -E -F.

Oops.  Studying that again, i come to the conclusion that you are right.

So we are not required to change it.

 - in favour of change: erroring out is a bit less error prone
 - against change: not erroring out is potentially more useful
   because it allows overriding when playing with aliases and
   with concatenation of option lists
 - in favour of change: but the above games are dangerous and can
   trap people with non-portable behaviour
 - against change: every change risks breaking people's scripts
 - against change: other implementations differ from each other,
   so we would just trade one portability issue for another

So, no clear argument either way, which probably means that it should
be left alone...

Sorry for my confusion,
  Ingo

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: grep -E -F

Theo de Raadt-2
> > That also says:
> >
> > The use of conflicting mutually-exclusive arguments produces undefined
> > results, unless a utility description specifies otherwise.
> >
> > In that paragraph, "application" refers to the thing invoking the utility. So
> > a conforming script/user/etc is prohibited from calling grep -E -F.
>
> Oops.  Studying that again, i come to the conclusion that you are right.
>
> So we are not required to change it.
>
>  - in favour of change: erroring out is a bit less error prone
>  - against change: not erroring out is potentially more useful
>    because it allows overriding when playing with aliases and
>    with concatenation of option lists
>  - in favour of change: but the above games are dangerous and can
>    trap people with non-portable behaviour
>  - against change: every change risks breaking people's scripts
>  - against change: other implementations differ from each other,
>    so we would just trade one portability issue for another
>
> So, no clear argument either way, which probably means that it should
> be left alone...

if (Fflag && Eflag) {
        fprintf(stderr, "                 ----------\n");
        fprintf(stderr, "                /          \\\n");
        fprintf(stderr, "               /    REST    \\\n");
        fprintf(stderr, "              /      IN      \\\n");
        fprintf(stderr, "             /     PEACE      \\\n");
        fprintf(stderr, "            /                  \\\n");
        fprintf(stderr, "            |    __progname    |\n");
        fprintf(stderr, "            |       0 Au       |\n");
        fprintf(stderr, "            |   killed by an   |\n");
        fprintf(stderr, "            |    undefined     |\n");
        fprintf(stderr, "            |    behaviour     |\n");
        fprintf(stderr, "            |       2017       |\n");
        fprintf(stderr, "           *|     *  *  *      | *\n");
        fprintf(stderr, "  _________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n");
        reboot(RB_NOSYNC);
        abort();
}

Or, we stick to the existing undefined behaviour, which is assuredly
compatible with behaviours people have in scripts written in the last
30 years.

If you want strict behaviours, you write a new command.  Then collect
a user community for it.  Over time, watch the things you didn't
define strictly build up... until you find yourself in similar
circumstances...

Loading...