There is a variable POSIXLY_CORRECT in Bash
POSIXLY_CORRECT
If this variable is in the environment when Bash starts, the shell enters POSIX mode (see Bash POSIX Mode) before reading the startup files, as if the --posix invocation option had been supplied. If it is set while the shell is running, Bash enables POSIX mode, as if the command
set -o posix
had been executed.
I was told that some options of grep
are not POSIX and so I confirmed in The Open Group Base Specifications Issue 6 for grep
. So I checked the GNU grep manual and found:
grep comes with a rich set of options: some from POSIX and some being GNU extensions. Long option names are always a GNU extension, even for options that are from POSIX specifications. Options that are specified by POSIX, under their short names, are explicitly marked as such to facilitate POSIX-portable programming. A few option names are provided for compatibility with older or more exotic implementations.
And it also mentions:
2.2 Environment Variables
The behavior of grep is affected by the following environment variables.
POSIXLY_CORRECT
If set, grep behaves as POSIX requires; otherwise, grep behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options. Also, POSIXLY_CORRECT disables special handling of an invalid bracket expression. See invalid-bracket-expr.
Using the part Long option names are always a GNU extension, even for options that are from POSIX specifications I said: let's try the variable POSIXLY_CORRECT against that.
So I did try with something that is not POSIX:
$ echo "HELLO" | grep --ignore-case 'hello'
HELLO
But to my surprise it also works setting it:
$ echo "HELLO" | POSIXLY_CORRECT=1 grep --ignore-case 'hello'
HELLO
What am I doing wrong? Shouldn't a set POSIXLY_CORRECT make grep
not recognize a long option name?
The same occurs if using an option (for example -C
) that is not POSIX:
$ POSIXLY_CORRECT=1 grep -C 2 '2' <<< "1
2
3"
1
2
3
As well as doing all the same running set -o posix
before.
From the GNU grep
manual:
POSIXLY_CORRECT
If set,
grep
behaves as POSIX requires; otherwise,grep
behaves more like other GNU programs. POSIX requires that options that follow file names must be treated as file names; by default, such options are permuted to the front of the operand list and are treated as options. Also, POSIX requires that unrecognized options be diagnosed as "illegal", but since they are not really against the law the default is to diagnose them as "invalid".POSIXLY_CORRECT
also disables_N_GNU_nonoption_argv_flags_
, described below.
This means that the only thing that setting POSIXLY_CORRECT
in the environment does for GNU grep
is that it's not allowed to rearrange options that occur after the filename so that the are placed at the front. It doesn't make it not take non-POSIX command line flags.
So let's try that:
$ ggrep "hello" myfile -v
$ env POSIXLY_CORRECT=1 ggrep "hello" myfile -v
ggrep: -v: No such file or directory
(GNU grep
is called ggrep
on my BSD system)
The part about "unrecognized options" in the manual is what GNU grep
does by default, i.e. the -g
flag will be diagnosed as "invalid" under both with POSIXLY_CORRECT
and without. Since e.g. --ignore-case
is a valid option (though not POSIX), this is not diagnosed as "invalid" with POSIXLY_CORRECT
.
In general, check the documentation for external utilities for how they behave under POSIXLY_CORRECT
(if they care at all). The bash
manual can only tell you how the shell and its built-in commands are affected by this environment variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With