Как использовать POSIXLY CORRECT в grep?

есть переменная POSIXLY_CORRECT в bash

POSIXLY_CORRECT

если эта переменная находится в среде при запуске Bash, оболочка входит в режим POSIX (см. Режим bash POSIX) перед чтением запуска файлы, как если бы была предоставлена опция вызова --posix. Если это установите во время работы оболочки, Bash включает режим POSIX, как если бы команда

set -o posix

было выполненный.

мне сказали, что некоторые варианты grep не POSIX, и поэтому я подтвердил в открытая группа базовых спецификаций выпуск 6 для grep. Поэтому я проверил руководство GNU grep и

grep поставляется с богатым набором опций: некоторые из POSIX и некоторые из расширений GNU. Длинные имена опций всегда являются расширением GNU, даже для опций, которые из спецификаций POSIX. Опции это указанные POSIX под их короткими именами явно помечаются как такие, чтобы облегчить POSIX-портативное Программирование. Несколько имен опций предусмотрено для совместимости со старыми или более экзотическими реализациями.

и он также упоминает:

2.2 Переменные Среды

на поведение grep влияют следующие переменные среды.

POSIXLY_CORRECT
Если установлено, grep ведет себя так, как требует POSIX; в противном случае grep ведет себя больше как другие программы GNU. POSIX требует, чтобы параметры, следующие за именами файлов, обрабатывались как имена файлов; по умолчанию такие параметры переставляются в начало списка операндов и обрабатываются как параметры. Кроме того, POSIXLY_CORRECT отключает специальную обработку недопустимого выражения скобки. Увидеть недействительным-кронштейн-выражение.

частью долго имена опций всегда являются расширением GNU, даже для опций из спецификаций POSIX я сказал: давайте попробуем переменную POSIXLY_CORRECT против этого.

поэтому я попытался с чем-то, что не POSIX:

$ echo "HELLO" | grep --ignore-case 'hello'
HELLO

но к моему удивлению все работает и устанавливая это:

$ echo "HELLO" | POSIXLY_CORRECT=1 grep --ignore-case 'hello'
HELLO

что я делаю не так? Не должен ли набор POSIXLY_CORRECT make grep не распознать длинное имя опции?

то же самое происходит при использовании опции (например -C) это не POSIX:

$ POSIXLY_CORRECT=1 grep -C 2 '2' <<< "1
2
3"
1
2
3

а также делать все то же работает set -o posix раньше.

2 ответов


из GNU grep руководство:

POSIXLY_CORRECT

если установлено, grep ведет себя так, как требует POSIX; в противном случае,grep ведет себя больше как другие программы GNU. POSIX требует, чтобы параметры имени файла должны рассматриваться как имена файлов ; по умолчанию такие параметры переставляются на переднюю часть список операндов и рассматриваются как опции. Кроме того, POSIX требует, чтобы непризнанные варианты были диагностированы как " незаконные", но поскольку они на самом деле не против закона, дефолт диагностировать их как "недействительные". POSIXLY_CORRECT также отключает _N_GNU_nonoption_argv_flags_, описано ниже.

это означает, что единственное, что параметр POSIXLY_CORRECT в среде делает для GNU grep это то, что не разрешено переставлять параметры, которые происходят после имени файла, так что они помещаются спереди. Он не делает его не принимать флаги командной строки non-POSIX.

так давайте попробуем это:

$ ggrep "hello" myfile -v

$ env POSIXLY_CORRECT=1 ggrep "hello" myfile -v
ggrep: -v: No such file or directory

(GNU grep называется ggrep в моей системе BSD)

часть о" непризнанных параметрах " в руководстве-это то, что GNU grep происходит по умолчанию, т. е. -g флаг будет диагностирован как "недействительный" под обоими с POSIXLY_CORRECT и без. Так, например,--ignore-case это допустимый вариант (хотя и не POSIX), это не диагностируется как "недействительный" с POSIXLY_CORRECT.

в общем, проверьте документацию для внешних утилит для того, как они ведут себя под POSIXLY_CORRECT (если они вообще заботятся). The bash руководство может только сказать вам, как оболочка и ее встроенные команды зависят от этой переменной среды.


во-первых, в целом POSIXLY_CORRECT переменная, которая используется несколькими инструментами GNU и библиотечными функциями, является попыткой быть более корректной, это не гарантирует, что инструменты GNU ведут себя сильно в соответствии с POSIX.


GNU grep сам не читает POSIXLY_CORRECT переменная вообще, когда дело доходит до разбора опций. GNU grep использует функцию glibc getopt_long для разбора это варианты. Эта функция уважает POSIXLY_CORRECT переменной окружения, но только в ограниченном путь. Проверка man getopt_long:

POSIXLY_CORRECT

если это установлено, то обработка параметров останавливается, как только встречается аргумент nonoption.

... и исходный код GNU grep

это поведение одинаково для всех программ, которые связываются с glibc и используют getopt_long. Это не относится к grep.