Farbige Grep-Ausgabe: Nicht GREP_OPTIONS kein Alias

10

Ich möchte farbige Ausgabe von grep.

.... Aber

  • Strategie 1: GREP_OPTIONS. Dies ist jedoch veraltet. Siehe http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS sehen auf den ersten Blick wie eine Lösung aus, aber das macht etwas anderes.
  • Strategie 3: Alias. Dies funktioniert nicht find ... | xargs grep, da xargs keine Aliase auswertet.
  • Strategie 4: Schreiben Sie ein einfaches Wrapper-Skript. Nein, ich denke, das ist zu schmutzig und macht mehr Ärger als es löst.
  • Strategie 5: Patchen Sie den Quellcode
  • Strategie 6: Wenden Sie sich an grep-Entwickler und fordern Sie einen Ersatz für GREP_OPTIONS an
  • Strategie NICE-and-EASY: ... das fehlt. Ich habe keine Ahnung.

Wie kann man das lösen?

Vielen Dank für Ihren Versuch zu helfen!

... aber ich kann das Kopfgeld nicht geben

Nennen Sie mich unhöflich, arogant, beleidigend, missbräuchlich ...

Ich sehe nur Workarounds - keine Lösung. Keine Antwort befriedigte die Frage.

Vielen Dank für deine Mühe.

guettli
quelle
1
Sie haben zwei Vorschläge zur Verwendung eines Wrapper-Skripts (Ihre Strategie 4) als "nicht wirklich eine Antwort" abgelehnt. Können Sie beschreiben, was "schmutzig", "lästig" oder "nicht wirklich eine Antwort" ist? Vielleicht ist das ein separates Problem, das umgangen werden kann.
JigglyNaga
2
Strategie 5 ist das color_option2
Patchen
2
@ JigglyNaga hier ist meine Erklärung, warum ein Wrapper-Skript keine Lösung ist. Unser Team verwaltet mehrere Server. Momentan weniger als tausend, aber die Zahl steigt. Ja, wir verwenden das Konfigurationsmanagement und es wäre einfach, ein Skript für alle bereitzustellen. Aber ich möchte, dass die Dinge einfach und unkompliziert sind (denken Sie an neue Mitglieder im Team. Ich möchte sie nicht verwirren). Die --colorOption hat bereits den Wert auto. Ich weiß nur nicht, warum Sie es nicht standardmäßig aktivieren können.
Guettli
Sie sollten Strategie 4 oder 5 verwenden - ich würde Strategie 4 mit einem minimalen Strich / Sh-Skript ( exec grep --color=auto "$@") bevorzugen , optional mit einem anderen Namen ( grepcoder colorgrep). Dies hat einen vernachlässigbaren Overhead (und keine zusätzlichen gleichzeitigen Prozesse zur Laufzeit). Der Grund, warum Sie sie als "nicht einfach genug" bezeichnet haben, ist die Tatsache, dass Sie diese Funktion nicht als nützlich genug erachten, um den (relativ geringen) einmaligen Aufwand für ihre Implementierung aufzuwenden, und nach jemand anderem suchen, der sie für Sie erledigt. Aus diesem Grund sind Ihre "nicht wirklich eine Antwort" -Kommentare zu den geposteten Antworten ziemlich unhöflich.
Nominelles Tier
1
@NominalAnimal Ja, Sie haben Recht "nicht wirklich eine Antwort" klingt unhöflich. Ich bin kein Muttersprachler. Welcher Wortlaut (Übermittlung derselben Nachricht) wäre besser?
Guettli

Antworten:

13

Einige der Gründe, aus denen OP angegeben hat, dass die Optionen ungeeignet sind, haben in der Realität keine Grundlage. Hier zeige ich, welche Auswirkungen die Strategie 4 von OP hat:


Wird bei den meisten Distributionen grepin /bin(typisch) oder /usr/bin(OpenSUSE, möglicherweise in anderen) installiert und PATHenthält standardmäßig /usr/local/binvor /binoder /usr/bin. Dies bedeutet , dass , wenn Sie erstellen /usr/local/bin/grepmit

#!/bin/sh
exec /bin/grep --color=auto "$@"

Wo /bin/shist eine POSIX-kompatible Shell, die von Ihrer Distribution bereitgestellt wird, normalerweise Bash oder Dash. Wenn drin grepist /usr/bin, dann mach das

#!/bin/sh
exec /usr/bin/grep --color=auto "$@"

Der Overhead dieses Skripts ist minimal. Die execAnweisung bedeutet, dass der Skriptinterpreter durch die grepBinärdatei ersetzt wird. Dies bedeutet, dass die Shell während grepder Ausführung nicht im Speicher verbleibt . Somit ist der einzige Overhead eine zusätzliche Ausführung des Skriptinterpreters, dh eine kleine Latenz in der Wanduhrzeit. Die Latenz ist ungefähr konstant (hängt nur davon ab, ob grepund shsich bereits im Seitencache befinden oder nicht und wie viel E / A-Bandbreite verfügbar ist) und hängt nicht davon ab, wie lange sie grepausgeführt wird oder wie viele Daten verarbeitet werden.

Wie lange dauert diese Latenz, dh der vom Wrapper-Skript hinzugefügte Overhead?

Um dies herauszufinden, erstellen Sie das obige Skript und führen Sie es aus

time /bin/grep --version
time /usr/local/bin/grep --version

Auf meinem Computer benötigt Ersteres 0,005 Sekunden in Echtzeit (über eine große Anzahl von Läufen), während Letzteres 0,006 Sekunden in Echtzeit benötigt. Daher beträgt der Aufwand für die Verwendung des Wrappers auf meinem Computer 0,001 s (oder weniger) pro Aufruf.

Das ist unbedeutend.

Ich sehe auch nichts "Schmutziges" daran, weil viele gängige Anwendungen und Dienstprogramme denselben Ansatz verwenden. Um die Liste solcher auf Ihrem Computer in /binund /usr/binanzuzeigen, führen Sie sie einfach aus

file /bin/* /usr/bin/* | sed -ne 's/:.*shell script.*$//p'

Auf meinem Rechner enthält die obige Ausgabe egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, und xfig, das ich ziemlich oft. Wenn Sie Ihre gesamte Distribution nicht als "schmutzig" betrachten, weil Sie sich auf Wrapper-Skripte verlassen, haben Sie keinen Grund, solche Wrapper-Skripte als "schmutzig" zu betrachten.


Bei Problemen kann ein solches Wrapper-Skript Folgendes verursachen:

Wenn nur menschliche Benutzer (im Gegensatz zu Skripten gegen) werden mit der Version von grep , dass standardmäßig Farbunterstützung , wenn Ausgabe an einen Terminal ist, dann kann der Wrapper - Skript benannt werden colorgrepoder cgrepoder was auch immer der OP sieht fit.

Dies vermeidet alle möglichen Kompatibilitätsprobleme, da sich das Verhalten von grepüberhaupt nicht ändert.


Aktivieren von grepOptionen mit einem Wrapper-Skript, jedoch auf eine Weise, die neue Probleme vermeidet:

Wir können das Wrapper-Skript einfach umschreiben, um eine benutzerdefinierte Datei zu unterstützen, GREP_OPTSauch wenn GREP_OPTIONSsie nicht unterstützt wird (da sie bereits veraltet ist). Auf diese Weise können Benutzer einfach export "GREP_OPTIONS=--color=auto"oder ähnlich zu ihrem Profil hinzufügen . /usr/local/bin/grepist dann

#!/bin/sh
exec /bin/grep $GREP_OPTIONS "$@"

Beachten Sie, dass keine Anführungszeichen vorhanden sind $GREP_OPTIONS, sodass Benutzer mehr als eine Option angeben können.

Auf meinem System ist die Ausführung time /usr/local/bin/grep --versionmit GREP_OPTIONSleer oder mit GREP_OPTIONS=--color=autogenauso schnell wie in der vorherigen Version des Wrapper-Skripts. Das heißt, die Ausführung dauert normalerweise eine Millisekunde länger als normal grep.

Diese letzte Version würde ich persönlich zur Verwendung empfehlen.


Zusammenfassend die Strategie 4 von OP:

  • wird bereits von grepEntwicklern empfohlen

  • ist trivial zu implementieren (zwei Zeilen)

  • hat einen unbedeutenden Overhead (eine Millisekunde zusätzliche Latenz pro Aufruf auf diesem bestimmten Laptop; auf jedem Computer leicht zu überprüfen)

  • kann als Wrapper-Skript implementiert werden, das GREP_OPTSUnterstützung hinzufügt (um veraltete / nicht unterstützte zu ersetzen GREP_OPTIONS)

  • kann implementiert werden (als colorgrep/ cgrep), ohne dass Skripte oder vorhandene Benutzer betroffen sind

Da es sich um eine Technik handelt, die bereits in Linux-Distributionen weit verbreitet ist, handelt es sich um eine gängige Technik, die nicht "schmutzig" ist.

Wenn es als separater Wrapper ( colorgrep/ cgrep) implementiert wird , kann es keine neuen Probleme verursachen, da es das grepVerhalten überhaupt nicht beeinflusst . Wenn es als Wrapper-Skript implementiert wird, das GREP_OPTSUnterstützung hinzufügt , GREP_OPTS=--color=autobirgt die Verwendung genau die gleichen Risiken (z. B. Probleme mit vorhandenen Skripten) wie das vorgelagerte Hinzufügen von Standard --color=auto. Daher ist der Kommentar, dass dies "mehr Probleme schafft als löst", völlig falsch: Es werden keine zusätzlichen Probleme erstellt.

Nominelles Tier
quelle
3

Die Dokumentation, die Sie mit der ersten Strategie bereitstellen, lautet:

Bitte verwenden Sie stattdessen einen Alias ​​oder ein Skript. Wenn sich grep beispielsweise im Verzeichnis '/ usr / bin' befindet, können Sie Ihrem PATH $ HOME / bin voranstellen und ein ausführbares Skript $ HOME / bin / grep erstellen, das Folgendes enthält:

#! /bin/sh
export PATH=/usr/bin
exec grep --color=auto --devices=skip "$@"

Wenn der Alias ​​für Sie nicht möglich ist, ist das Wrapper-Skript der einzige Weg.

stderr
quelle
Das ist Strategie 4 ... keine wirkliche Antwort.
Guettli
3

Der Grund, warum die GREP_OPTIONSVariable veraltet ist, besteht darin, dass sie Probleme verursacht, wenn grepsie irgendwo in einem Skript aufgerufen wird und das Skript nicht mit den alternativen Optionen funktioniert, die von der Variablen stammen. Wenn Sie ein Wrapper-Skript für schreiben grep, haben Sie das gleiche Problem, es sei denn, Sie geben ihm einen anderen Namen .

$ cat ~/bin/cgrep
#!/bin/sh
exec grep --color=always "$@"
$ find  -exec cgrep  {} +

Alternativ können Sie Ihre bevorzugten Optionen in einer Variablen speichern. In anderen Shells als zsh ist dies umständlich, wenn die Optionen Platzhalterzeichen ( \[*?) enthalten. Andernfalls können Sie einfach die Variable ohne Anführungszeichen verwenden, um einen Befehl mit Argumenten abzurufen.

cgrep=(grep --color=always)
find  -exec $cgrep  {} +

Beachten Sie, dass GNU und BSD grep einen Verzeichnisbaum rekursiv verarbeiten können, wodurch die Notwendigkeit einer findKombination in den grepmeisten Fällen verringert wird .

Gilles 'SO - hör auf böse zu sein'
quelle
1
Das ist Strategie 4 ... keine wirkliche Antwort.
Guettli
@guettli, das ist die richtige Antwort. Wenn Sie einen Befehl mit einem anderen Verhalten wünschen grep, benötigen Sie einen Befehl mit einem anderen Namen. Wenn Sie denselben Namen beibehalten, werden Skripte unterbrochen, die das ursprüngliche / Standardverhalten erwarten. Das ist das sauberste und verursacht keine zusätzlichen Probleme .
Stéphane Chazelas
@ StéphaneChazelas ja du hast recht. Dies ist die richtige Antwort aus Ihrer Sicht.
Guettli
1

Am einfachsten ist es, einen Alias ​​zu verwenden (Strategie 3). Wenn Sie sich wirklich für den xargsBefehl interessieren , können Sie ihn dennoch mit einer Bash-Funktion überschreiben.

alias grep='grep --color'
xargs() {
    local args
    for ((i=1; i<=$#; i++))
    do
            if [[ "-E -L -P -I -s -d" == *"${!i}"* ]]; then
                    ((i=i+1))
            elif [[ ${!i:0:1} != "-" ]]; then
                    if [[ ${!i} == "grep" ]]; then
                            args="--color"
                    fi
                    /usr/bin/xargs ${@:1:i} $args ${@:i+1}
                    return;
            fi
    done
}

Dies ist jedoch nicht besser als die Verwendung eines Wrapper-Befehls, der vom grepTeam als empfohlene Lösung angesehen wird :

/usr/local/bin/grep:

#!/bin/bash
/bin/grep --color "$@"

Meiner bescheidenen Meinung nach sollten Sie sich an das grepEntwicklerteam wenden , um sie zu bitten, einen einfachen Ersatz für die GREP_OPTIONSVariable bereitzustellen, der die Farbe grepgemäß einer Umgebungsvariablen ermöglicht.

Es wäre für sie recht einfach, die colorOption standardmäßig zu aktivieren oder wenn die GREP_COLORSfestgelegt wurde.

Adam
quelle
1
Vielen Dank für "... Sie sollten sich an das grep-Entwicklerteam wenden ...". Dies gibt mir positives Feedback. Jetzt weiß ich, dass ich nicht der einzige bin, der denkt, dass hier etwas fehlt.
Guettli
Ich habe Ihren Kommentar "... Sie sollten sich an das grep-Entwicklerteam wenden ..." als Strategie6 zur Frage hinzugefügt. Bisher ist dies meine Lieblingsantwort.
Guettli
0

Dies ist die Lösung aus der Top-Antwort von @NominalAnimal, jedoch mit den üblichen grep: ...Warnungen (anstelle von /bin/grep: ...):

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
Kirill Bulygin
quelle
Ich kann Wrapper schreiben. Ein Wrapper ist in diesem Zusammenhang keine Lösung.
Guettli
@guettli Nun, die Antwort sollte nicht genau auf Ihre Situation eingehen ... Wenn Kommentare dieselben Formatierungsfunktionen wie Antworten hätten, wäre das ein Kommentar. (Und ich hatte ähnliche Änderungen abgelehnt, die nicht vom ursprünglichen Autor oder so beabsichtigt waren.) Was Ihre Situation betrifft, denke ich, dass eine richtige wörtliche Antwort auf Ihre Frage lautet: dass es keine andere "Strategie NICE-and-EASY" gibt.
Kirill Bulygin