2016-07-27 57 views
5

Jest zmienna POSIXLY_CORRECT w BashJak korzystać z POSIXLY_CORRECT w grep?

POSIXLY_CORRECT

Jeśli zmienna ta jest w środowisku podczas uruchamiania bash, powłoka przechodzi w tryb POSIX (patrz Bash Tryb POSIX) przed przeczytaniem starcie plików tak jakby podano opcję wywołania -posix. Jeśli jest zestaw podczas gdy powłoka jest uruchomiony, bash włącza tryb POSIX, jakby polecenie

set -o posix 

został stracony.

Powiedziano mi, że niektóre opcje grep nie są POSIX-ami i dlatego potwierdziłem w The Open Group Base Specifications Issue 6 for grep. Więc sprawdziłem GNU grep manual Znalezione

grep jest wyposażony w bogaty zestaw opcji: niektóre z POSIX i niektóre będące rozszerzeniami GNU. Długie nazwy opcji są zawsze rozszerzeniem GNU, , nawet dla opcji, które pochodzą ze specyfikacji POSIX. Opcje oznaczone jako POSIX pod ich krótkimi nazwami są wyraźnie oznaczone jako w celu ułatwienia programowania przenośnego POSIX. Kilka nazw opcji to: pod warunkiem zgodności ze starszymi lub bardziej egzotycznymi implementacjami.

I to również jest mowa o:

2.2 Environment Variables

Zachowanie grep mają wpływ następujące zmienne środowiskowe.

POSIXLY_CORRECT
Jeśli jest ustawiona, to grep zachowuje się jak wymaga POSIX; w przeciwnym razie grep zachowuje się bardziej jak inne programy GNU. POSIX wymaga, aby opcje występujące po nazwach plików były traktowane jak nazwy plików; domyślnie takie opcje są permutowane z przodu listy argumentów operacji i są traktowane jako opcje. Ponadto POSIXLY_CORRECT wyłącza specjalne traktowanie nieprawidłowego wyrażenia nawiasów. Zobacz invalid-bracket-expr.

Korzystanie z częścią długie nazwy opcji są zawsze rozszerzenie GNU, nawet dla opcji, które są ze specyfikacją POSIX I powiedział: Spróbujmy zmienna POSIXLY_CORRECT przeciwko temu.

więc nie spróbować z czymś, co nie jest POSIX:

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

Ale ku mojemu zaskoczeniu działa również ustawienie go:

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

Co robię źle? Czy nie należy ustawić, aby w pliku POSIXLY_CORRECT grep rozpoznawano długą nazwę opcji?

To samo dzieje się w przypadku korzystania z opcji (np -C), które nie jest POSIX:

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

Jak również robi wszystko samo bieganie set -o posix wcześniej.

+0

'grep' to program zewnętrzny, nie jest częścią powłoki. – Barmar

+0

Wypróbuj 'export POSIXLY_CORRECT' – cdarke

+1

@cdarke Kiedy umieścisz przypisanie zmiennej na początku polecenia, wyeksportuje je automatycznie. – Barmar

Odpowiedz

6

z podręcznika GNU grep:

POSIXLY_CORRECT

Jeśli ustawione, grep zachowuje się jak wymaga POSIX; w przeciwnym razie, grep zachowuje się bardziej jak inne programy GNU. POSIX wymaga, aby opcje następujące po nazwach plików były traktowane jako nazwy plików; domyślnie takie opcje są permutowane na początku listy operandów i są traktowane jako opcje. Ponadto, POSIX wymaga, aby nierozpoznane opcje były diagnozowane jako "nielegalne", , ale ponieważ nie są tak naprawdę niezgodne z prawem, domyślną wartością jest w celu zdiagnozowania ich jako "nieważnych". POSIXLY_CORRECT wyłącza również _N_GNU_nonoption_argv_flags_, opisane poniżej.

Oznacza to, że jedyną rzeczą, że ustawienie POSIXLY_CORRECT w środowisku robi dla GNU grep jest to, że nie jest dozwolone, aby zmienić opcje, które występują po nazwie pliku tak, że umieszczone są na froncie. Nie powoduje, że nie przyjmuje ona flag linii poleceń innych niż POSIX.

Więc spróbujmy, że:

$ ggrep "hello" myfile -v 

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

(GNU grep nazywa ggrep w moim systemie BSD)

część o "nierozpoznane opcje" w podręczniku, co GNU grep robi domyślnie, czyliflaga -g zostanie zdiagnozowana jako "nieprawidłowa" pod kodem POSIXLY_CORRECT i bez. Ponieważ np. --ignore-case jest prawidłową opcją (ale nie POSIX), to nie jest diagnozowane jako "nieważne" z POSIXLY_CORRECT.

Ogólnie sprawdź w dokumentach zewnętrznych programów narzędziowych, jak zachowują się one pod numerem POSIXLY_CORRECT (jeśli w ogóle się nimi przejmują). W instrukcji bash można tylko powiedzieć, w jaki sposób ta zmienna środowiskowa wpływa na powłokę i jej wbudowane komendy.

+2

Pokonałeś mnie o wąski margines. Być może podkreśl, że dokumentacja dla Bash dotyczy tylko Basha, a ustawienie 'POSIXLY_CORRECT' robi dla' grep' dokładnie to, co robi instrukcja 'grep'. – tripleee

1

Po pierwsze, ogólnie zmienna POSIXLY_CORRECT, która jest używana przez kilka narzędzi GNU i funkcji bibliotecznych, jest próbą poprawienia się bardziej posixly, nie gwarantuje, że narzędzia GNU zachowują się silnie zgodnie z POSIX.


GNU grep sama nie czyta zmiennej POSIXLY_CORRECT w ogóle, jeśli chodzi o opcji analizowania. GNU grep używa funkcji glibc getopt_long do analizy jego opcji. Ta funkcja respektuje zmienną środowiskową POSIXLY_CORRECT, ale tylko w ograniczonym zakresie. Sprawdzić man getopt_long:

POSIXLY_CORRECT

Jeśli jest ustawiony, a następnie przetwarzanie opcja przestaje jak tylko argument nonoption spotyka.

... i kod źródłowy GNU grep

Takie zachowanie jest takie samo dla wszystkich programów, które są linkami przeciwko glibc i korzystających getopt_long. Nie jest to specyficzne dla grep.

+0

Więc to było moje nieporozumienie w tej zmiennej. Myślałem, że POSIXLY_CORRECT sprawi, że wrócę do historii do wersji POSIX 'grep', która nie jest. – fedorqui

+0

Nie, nie jest. Myślę, że zawsze jest to kompromisem złożoności kodu, wydajności, kompatybilności wstecznej i tak, zgodność z POSIX :) – hek2mgl