2016-07-27 25 views
5

Es ist eine Variable POSIXLY_CORRECT in BashWie verwendet man POSIXLY_CORRECT in Grep?

POSIXLY_CORRECT

Wenn diese Variable in der Umgebung ist, wenn Bash beginnt, die Shell POSIX-Modus (siehe Bash POSIX-Modus) vor dem Lesen Sie den Start Dateien eingibt, als wäre die Aufrufoption --posix geliefert worden. Wenn es Satz, während die Shell ausgeführt wird, ermöglicht Bash POSIX-Modus, als ob der Befehl

set -o posix 

hatte ausgeführt worden ist.

Ich wurde gesagt, dass einige Optionen von grep sind nicht POSIX und so habe ich in The Open Group Base Specifications Issue 6 for grep bestätigt. So überprüfte ich die GNU grep manual und gefunden:

grep mit einem umfangreichen Satz von Optionen kommt: einige von POSIX und einigen Erweiterungen ist GNU. Lange Optionsnamen sind immer eine GNU-Erweiterung, auch für Optionen, die aus POSIX-Spezifikationen stammen. Optionen, die sind, die von POSIX unter ihren kurzen Namen angegeben werden, werden explizit als gekennzeichnet, um POSIX-portable Programmierung zu erleichtern. Einige Optionsnamen sind , die für Kompatibilität mit älteren oder exotischeren Implementierungen bereitgestellt werden.

Und es erwähnt auch:

2.2 Environment Variables

Das Verhalten von grep durch die folgenden Umgebungsvariablen beeinflusst wird.

POSIXLY_CORRECT
Wenn gesetzt, verhält sich grep wie POSIX erfordert; Ansonsten verhält sich Grep mehr wie andere GNU-Programme. POSIX erfordert, dass Optionen, die auf Dateinamen folgen, als Dateinamen behandelt werden müssen. Standardmäßig werden solche Optionen an die Vorderseite der Operandenliste permutiert und als Optionen behandelt. Außerdem deaktiviert POSIXLY_CORRECT die spezielle Behandlung eines ungültigen Klammerausdrucks. Siehe invalid-bracket-expr.

Mit den Teil Langoptionsnamen sind immer eine GNU-Erweiterung, auch für Optionen, die von POSIX-Spezifikationen sind Ich sagte: Lassen Sie uns die Variable POSIXLY_CORRECT dagegen versuchen.

Also habe ich mit etwas versuchen, das nicht POSIX ist:

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

Aber zu meiner Überraschung Einstellung funktioniert es auch:

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

Was mache ich falsch? Sollte ein Set POSIXLY_CORRECT grep keinen langen Optionsnamen erkennen lassen?

Das gleiche geschieht, wenn eine Option (zum Beispiel -C), die nicht POSIX ist:

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

Neben tun alle die gleiche Lauf set -o posix vor.

+0

'grep' ist ein externes Programm, es ist nicht Teil der Shell. – Barmar

+0

Versuchen Sie 'export POSIXLY_CORRECT' – cdarke

+1

@cdarke Wenn Sie eine Variablenzuweisung am Anfang des Befehls setzen, wird sie automatisch exportiert. – Barmar

Antwort

6

Von der GNU grep Handbuch:

POSIXLY_CORRECT

Wenn gesetzt, grep verhält sich wie POSIX erfordert; Ansonsten verhält sich grep mehr wie andere GNU-Programme. POSIX erfordert, dass Optionen, die Dateinamen folgen, als Dateinamen behandelt werden müssen; Standardmäßig werden solche Optionen an die Vorderseite der Operandenliste permutiert und als Optionen behandelt. Außerdem erfordert POSIX , dass nicht erkannte Optionen als "illegal" diagnostiziert werden, , aber da sie nicht wirklich gegen das Gesetz sind, ist der Standard , um sie als "ungültig" zu diagnostizieren. POSIXLY_CORRECT deaktiviert auch _N_GNU_nonoption_argv_flags_, unten beschrieben. Diese

bedeutet, dass das einzige, was POSIXLY_CORRECT in der Umgebung Einstellung tut für GNU grep ist, dass es nicht erlaubt ist, Optionen neu zu ordnen, die nach dem Dateinamen auftreten, so dass die an der Vorderseite angeordnet sind. Es macht nicht nicht-POSIX-Befehlszeilenflags erforderlich.

lassen sich das so versuchen:

$ ggrep "hello" myfile -v 

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

(GNU grepggrep auf meinem BSD-System genannt wird)

Der Teil über "nicht erkennen Optionen" im Handbuch ist das, was GNU grep tut standardmäßig, das heißtDas Flag -g wird sowohl unter POSIXLY_CORRECT als auch ohne als "ungültig" diagnostiziert. Da z.B. --ignore-case ist eine gültige Option (wenn auch nicht POSIX), dies wird nicht als "ungültig" mit POSIXLY_CORRECT diagnostiziert.

Überprüfen Sie im Allgemeinen die Dokumentation für externe Dienstprogramme für, wie sie sich unter POSIXLY_CORRECT verhalten (wenn sie überhaupt interessieren). Das bash Handbuch kann Ihnen nur sagen, wie die Shell und ihre integrierten Befehle von dieser Umgebungsvariablen betroffen sind.

+2

Sie haben mich mit einem knappen Vorsprung geschlagen. Vielleicht betonen Sie, dass die Dokumentation für Bash nur für Bash gilt, und dass die 'POSIXLY_CORRECT' Einstellung für' grep' genau das tut, was das 'Grep' Handbuch sagt. – tripleee

1

Erstens ist die POSIXLY_CORRECT Variable, die von ein paar GNU-Tools und Bibliotheksfunktionen verwendet wird, ein Versuch, mehr korrekt zu sein, es garantiert nicht, dass sich GNU-Tools stark nach POSIX verhalten.


GNU grep selbst liest nicht die POSIXLY_CORRECT Variable überhaupt, wenn es um Option Parsing kommt. GNU Grep verwendet die Glibc-Funktion getopt_long, um die Optionen zu analysieren. Diese Funktion berücksichtigt die Umgebungsvariable POSIXLY_CORRECT nur eingeschränkt. Prüfen man getopt_long:

POSIXLY_CORRECT

Wenn dies gesetzt ist, dann Option Verarbeitung stoppt, sobald ein nonoption Argument begegnet.

... und der Quellcode von GNU grep

Dieses Verhalten ist das gleiche für alle Programme, die gegen glibc Verknüpfung und getopt_long verwenden. Es ist nicht spezifisch für grep.

+0

Also war es mein Missverständnis zu dieser Variable. Ich dachte, POSIXLY_CORRECT würde mich dazu bringen, in der Geschichte zur POSIX 'grep'-Version zurückzukehren, was nicht der Fall ist. – fedorqui

+0

Nein, ist es nicht. Ich schätze, es ist immer ein Kompromiss aus Code-Komplexität, Performance, Rückwärtskompatibilität und ja, Posix-Konformität :) – hek2mgl