Subject: Re: bug#49996: egrep and fgrep?

From: Paul Eggert <[email-masked]>
Date: Sun, 15 Aug 2021 11:10:59 -0700

On 8/15/21 7:25 AM, [email-masked] wrote:
> I'm willing to bet that the majority of grep/egrep/fgrep invocations
> come from the command line rather than from scripts.

That's not true for me, as I almost always invoke 'grep' via a script or 
shell function or Emacs. And I'm skeptical that it's true worldwide.

I doubt whether we should remove egrep and fgrep immediately, as that'd 
be a bit sudden. But it's a good time to take the next step. Proposed 
patch attached.
From 6bd26c3e37d63c431f0064a22d528f754c150ce1 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 15 Aug 2021 10:52:13 -0700
Subject: [PATCH] egrep, fgrep: now obsolete

* NEWS: Mention this.
* doc/Makefile.am (egrep.1 fgrep.1): Remove.  All uses removed.
* doc/grep.in.1, doc/grep.texi (grep Programs):
Remove documentation for egrep, fgrep.
* doc/grep.texi (Usage): Add FAQ for egrep and fgrep.
* src/Makefile.am (shell_does_substrings): Substitute for ${0##*/},
not for ${0%/\*} (which was not being used anyway).
* src/egrep.sh: Issue a obsolescence warning.
* tests/fedora: Use "grep -F" instead of "fgrep" in diagnostics,
as this tests "grep -F" not "fgrep".
---
 NEWS            |  5 +++++
 doc/.gitignore  |  2 --
 doc/Makefile.am | 11 ++---------
 doc/grep.in.1   | 13 +------------
 doc/grep.texi   | 36 ++++++++++++++++++++++++------------
 src/Makefile.am |  4 ++--
 src/egrep.sh    |  2 ++
 tests/fedora    |  4 ++--
 8 files changed, 38 insertions(+), 39 deletions(-)

diff --git a/NEWS b/NEWS
index 39a0903..4a62fb7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU grep NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Changes in behavior
+
+  The egrep and fgrep commands, which have been deprecated since
+  release 2.5.3 (2007), now warn that they are obsolescent and should
+  be replaced by grep -E and grep -F.
 
 * Noteworthy changes in release 3.7 (2021-08-14) [stable]
 
diff --git a/doc/.gitignore b/doc/.gitignore
index ac147d2..0151b94 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -1,6 +1,4 @@
-/egrep.1
 /fdl.texi
-/fgrep.1
 /gendocs_template
 /gendocs_template_min
 /grep.info*
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7075e8d..f6b9f4b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -19,20 +19,13 @@
 info_TEXINFOS = grep.texi
 grep_TEXINFOS = fdl.texi
 
-man_MANS = grep.1 fgrep.1 egrep.1
+man_MANS = grep.1
 
 EXTRA_DIST = grep.in.1
-CLEANFILES = grep.1 egrep.1 fgrep.1
+CLEANFILES = grep.1
 
 grep.1: grep.in.1
 	$(AM_V_GEN)rm -f $@-t $@
 	$(AM_V_at)sed 's/@''VERSION@/$(VERSION)/' $(srcdir)/grep.in.1 > $@-t
 	$(AM_V_at)chmod a=r $@-t
 	$(AM_V_at)mv -f $@-t $@
-
-egrep.1 fgrep.1: Makefile.am
-	$(AM_V_GEN)rm -f $@-t $@
-	$(AM_V_at)inst=`echo grep | sed '$(transform)'`.1 \
-	  && echo ".so man1/$$inst" > $@-t
-	$(AM_V_at)chmod a=r $@-t
-	$(AM_V_at)mv -f $@-t $@
diff --git a/doc/grep.in.1 b/doc/grep.in.1
index e8854f2..b014f65 100644
--- a/doc/grep.in.1
+++ b/doc/grep.in.1
@@ -137,7 +137,7 @@
 .hy 0
 .
 .SH NAME
-grep, egrep, fgrep \- print lines that match patterns
+grep \- print lines that match patterns
 .
 .SH SYNOPSIS
 .B grep
@@ -184,17 +184,6 @@ If no
 .I FILE
 is given, recursive searches examine the working directory,
 and nonrecursive searches read standard input.
-.PP
-In addition, the variant programs
-.B egrep
-and
-.B fgrep
-are the same as
-.B "grep\ \-E"
-and
-.BR "grep\ \-F" ,
-respectively.
-These variants are deprecated, but are provided for backward compatibility.
 .
 .SH OPTIONS
 .SS "Generic Program Information"
diff --git a/doc/grep.texi b/doc/grep.texi
index 63d2fc9..3236b98 100644
--- a/doc/grep.texi
+++ b/doc/grep.texi
@@ -1159,15 +1159,6 @@ combined with the @option{-z} (@option{--null-data}) option, and note that
 
 @end table
 
-In addition,
-two variant programs @command{egrep} and @command{fgrep} are available.
-@command{egrep} is the same as @samp{grep@ -E}.
-@command{fgrep} is the same as @samp{grep@ -F}.
-Direct invocation as either
-@command{egrep} or @command{fgrep} is deprecated,
-but is provided to allow historical applications
-that rely on them to run unmodified.
-
 
 @node Regular Expressions
 @chapter Regular Expressions
@@ -1918,7 +1909,7 @@ before giving it to @command{grep}, or turn to @command{awk},
 designed to operate across lines.
 
 @item
-What do @command{grep}, @command{fgrep}, and @command{egrep} stand for?
+What do @command{grep}, @option{-E}, and @option{-F} stand for?
 
 The name @command{grep} comes from the way line editing was done on Unix.
 For example,
@@ -1930,8 +1921,29 @@ global/regular expression/print
 g/re/p
 @end example
 
-@command{fgrep} stands for Fixed @command{grep};
-@command{egrep} stands for Extended @command{grep}.
+The @option{-E} option stands for Extended @command{grep}.
+The @option{-F} option stands for Fixed @command{grep};
+
+@item
+What happened to @command{egrep} and @command{fgrep}?
+
+7th Edition Unix had commands @command{egrep} and @command{fgrep}
+that were the counterparts of the modern @samp{grep -E} and @samp{grep -F}.
+Although breaking up @command{grep} into three programs was perhaps
+useful on the small computers of the 1970s, @command{egrep} and
+@command{fgrep} were not standardized by POSIX and are no longer needed.
+In the current GNU implementation, @command{egrep} and @command{fgrep}
+issue a warning and then act like their modern counterparts;
+eventually, they are planned to be removed entirely.
+
+If you prefer the old names, you can use use your own substitutes,
+such as a shell script named @command{egrep} with the following
+contents:
+
+@example
+#!/bin/sh
+exec grep -E "$@@"
+@end example
 
 @end enumerate
 
diff --git a/src/Makefile.am b/src/Makefile.am
index c2e6e9a..db1bb3f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -54,11 +54,11 @@ EXTRA_DIST = egrep.sh
 egrep fgrep: egrep.sh Makefile
 	$(AM_V_GEN)grep=`echo grep | sed -e '$(transform)'` &&		\
 	case $@ in egrep) option=-E;; fgrep) option=-F;; esac &&	\
-	shell_does_substrings='set x/y && d=$${1%/*} && test "$$d" = x' && \
+	shell_does_substrings='set x/y && d=$${1##*/} && test "$$d" = y' && \
 	if $(SHELL) -c "$$shell_does_substrings" 2>/dev/null; then	\
 	  edit_substring='s,X,X,';					\
 	else								\
-	  edit_substring='s,\$${0%/\*},`expr "X$$0" : '\''X\\(.*\\)/'\''`,g'; \
+	  edit_substring='s,\$${0##\*/},`expr "X$$0" : '\''X\\(.*\\)/'\''`,g'; \
 	fi &&								\
 	sed -e 's|[@]SHELL@|$(SHELL)|g'					\
 	    -e "$$edit_substring"					\
diff --git a/src/egrep.sh b/src/egrep.sh
index 6d6c15a..a0d1694 100644
--- a/src/egrep.sh
+++ b/src/egrep.sh
@@ -1,2 +1,4 @@
 #!@SHELL@
+cmd=${0##*/}
+echo "$cmd: warning: $cmd is obsolescent; using @grep@ @option@" >&2
 exec @grep@ @option@ "$@"
diff --git a/tests/fedora b/tests/fedora
index 43650f3..bd5527e 100755
--- a/tests/fedora
+++ b/tests/fedora
@@ -18,7 +18,7 @@ ok ()	{ printf "${G}OK${D}"; }
 fail () { printf "${R}FAIL${D} (See ${U})"; failures=1; }
 
 U=https://bugzilla.redhat.com/show_bug.cgi?id=116909
-printf "fgrep false negatives: "
+printf "grep -F false negatives: "
 cat > 116909.list <<EOF
 a
 b
@@ -59,7 +59,7 @@ if ( timeout --version ) > /dev/null 2>&1; then
   echo foobar | returns_ 124 timeout 10 grep -Fw "" && fail || ok
 
   U=https://bugzilla.redhat.com/show_bug.cgi?id=140781
-  printf 'fgrep hangs on binary files: '
+  printf 'grep -F hangs on binary files: '
   returns_ 124 timeout 10 grep -F grep "$abs_top_builddir/src/grep" \
     > /dev/null && fail || ok
 
-- 
2.30.2