Sortie grep colorée: pas GREP_OPTIONS pas alias

10

Je veux une sortie colorée de grep.

.... Mais

  • Stratégie 1: GREP_OPTIONS. Mais c'est obsolète. Voir http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS ressemble à première vue à une solution, mais cela fait quelque chose de différent.
  • Stratégie 3: alias. Cela ne fonctionne pas find ... | xargs grep, car xargs n'évalue pas les alias.
  • Stratégie 4: Écrivez un script wrapper simple. Non, je pense que c'est trop sale et fait plus de problèmes qu'il n'en résout.
  • Stratégie 5: patcher le code source
  • Stratégie 6: Contactez les développeurs grep, demandez un remplacement de GREP_OPTIONS
  • Stratégie NICE-and-EASY: ... cela manque. Je n'ai aucune idée.

Comment résoudre ça?

Merci d'avoir essayé d'aider!

... mais je ne peux pas donner la prime

Appelez-moi impoli, arogant, insultant, abusif ....

Je ne vois que des solutions - aucune solution. Aucune réponse n'a satisfait la question.

Merci pour vos efforts.

guettli
la source
1
Vous avez rejeté deux suggestions d'utiliser un script wrapper (votre stratégie 4) comme "pas vraiment une réponse". Pouvez-vous décrire ce qui est «sale», «gênant» ou «pas vraiment une réponse» à ce sujet? C'est peut-être un problème distinct qui peut être résolu.
JigglyNaga
2
Stratégie 5 est patcher le code source et ensemble color_optionpour2 ...
don_crissti
2
@JigglyNaga voici mon explication pourquoi un script wrapper n'est pas une solution. Notre équipe gère plusieurs serveurs. Moins de mille pour le moment, mais le nombre augmente. Oui, nous utilisons la gestion de configuration et il serait facile de déployer un script sur chacun d'eux. Mais je veux que les choses soient faciles et directes (pensez aux nouveaux membres de l'équipe. Je ne veux pas les confondre). L' --coloroption a déjà la valeur auto. Je ne sais tout simplement pas pourquoi vous ne pouvez pas l'activer par défaut.
guettli
Vous devez utiliser la stratégie 4 ou 5 - je préférerais la stratégie 4 avec un script dash / sh minimal ( exec grep --color=auto "$@"), éventuellement avec un nom différent ( grepcou colorgrep). Cela a une surcharge négligeable (et aucun processus simultané supplémentaire au moment de l'exécution). La raison pour laquelle vous les avez étiquetés "pas assez facile" est le fait que vous ne voyez pas cette fonctionnalité suffisamment utile pour consacrer l'effort ponctuel (relativement peu) de la mettre en œuvre et que vous cherchez quelqu'un d'autre pour le faire pour vous. Pour cette raison, vos commentaires "pas vraiment une réponse" aux réponses publiées sont assez grossiers.
Animal nominal
1
@NominalAnimal Oui, vous avez raison "pas vraiment une réponse" semble grossier. Je ne suis pas natif. Quelle formulation (transférer le même message) serait préférable?
guettli

Réponses:

13

Certaines des raisons pour lesquelles OP a déclaré que les options n'étaient pas appropriées n'ont aucun fondement dans la réalité. Ici, je montre quel type d'effets en utilisant la stratégie 4 de OP a:


Sur la plupart des distributions, grepest installé dans /bin(typique) ou /usr/bin(OpenSUSE, peut-être d'autres), et PATHcontient par défaut /usr/local/binavant /binou /usr/bin. Cela signifie que si vous créez /usr/local/bin/grepavec

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

/bin/shest un shell compatible POSIX fourni par votre distribution, généralement bash ou dash. Si grepest dedans /usr/bin, alors faites ça

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

Les frais généraux de ce script sont minimes. L' execinstruction signifie que l'interpréteur de script est remplacé par le grepbinaire; cela signifie que le shell ne reste pas en mémoire pendant grepson exécution. Ainsi, la seule surcharge est une exécution supplémentaire de l'interpréteur de script, c'est-à-dire une petite latence dans le temps d'horloge murale. La latence est à peu près constante (ne varie qu'en fonction de si grepet shdéjà dans le cache de pages et de la quantité de bande passante d'E / S disponible), et ne dépend pas de la durée d' grepexécution ou de la quantité de données qu'elle traite.

Alors, quelle est la durée de cette latence, c'est-à-dire la surcharge ajoutée par le script wrapper?

Pour le savoir, créez le script ci-dessus et exécutez

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

Sur ma machine, la première prend 0,005 s en temps réel (sur un grand nombre de cycles), tandis que la seconde prend 0,006 s en temps réel. Ainsi, la surcharge d'utilisation de l'encapsuleur sur ma machine est de 0,001 s (ou moins) par appel.

C'est insignifiant.

Je ne vois également rien de "sale" à ce sujet, car de nombreuses applications et utilitaires courants utilisent la même approche. Pour voir la liste de ces éléments sur votre machine /binet /usr/binexécutez simplement

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

Sur ma machine, la sortie comprend ci - dessus egrep, fgrep, zgrep, which, 7z, chromium-browser, lddet xfigque je l' utilise assez souvent. À moins que vous ne considériez votre distribution entière comme "sale" pour vous appuyer sur des scripts wrapper, vous n'avez aucune raison de considérer ces scripts wrapper comme "sales".


En ce qui concerne les problèmes, un tel script wrapper peut provoquer:

Si seuls les utilisateurs humains (par opposition aux scripts) utilisent la version de grep qui prend par défaut le support des couleurs si la sortie est vers un terminal, alors le script wrapper peut être nommé colorgrepou cgrepou ce que l'OP juge bon.

Cela évite tous les problèmes de compatibilité possibles, car le comportement de grepne change pas du tout.


Activation des grepoptions avec un script wrapper, mais d'une manière qui évite tout nouveau problème:

Nous pouvons facilement réécrire le script wrapper pour prendre en charge une personnalisation GREP_OPTSmême s'il GREP_OPTIONSn'était pas pris en charge (car il est déjà obsolète). De cette façon, les utilisateurs peuvent simplement ajouter export "GREP_OPTIONS=--color=auto"ou similaire à leur profil. /usr/local/bin/grepest alors

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

Notez qu'il n'y a pas de guillemets autour $GREP_OPTIONS, de sorte que les utilisateurs peuvent spécifier plusieurs options.

Sur mon système, l'exécution time /usr/local/bin/grep --versionavec GREP_OPTIONSvide ou avec GREP_OPTIONS=--color=autoest aussi rapide que la version précédente du script wrapper; c'est-à-dire, prend généralement une milliseconde de plus à exécuter que plain grep.

Cette dernière version est celle que je recommanderais personnellement d'utiliser.


En résumé, la stratégie 4 d'OP:

  • est déjà recommandé par les grepdéveloppeurs

  • est trivial à implémenter (deux lignes)

  • a des frais généraux insignifiants (une latence supplémentaire d'une milliseconde par appel sur cet ordinateur portable particulier; facilement vérifiée sur chaque machine)

  • peut être implémenté comme un script wrapper qui ajoute un GREP_OPTSsupport (pour remplacer obsolète / non pris en charge GREP_OPTIONS)

  • peut être implémenté (comme colorgrep/ cgrep) qui n'affecte pas du tout les scripts ou les utilisateurs existants

Parce que c'est déjà une technique largement utilisée dans les distributions Linux, c'est une technique courante et non "sale".

S'il est implémenté comme un wrapper séparé ( colorgrep/ cgrep), il ne peut pas créer de nouveaux problèmes car il n'affecte pas du tout le grepcomportement. S'il est implémenté en tant que script wrapper qui ajoute la GREP_OPTSprise en charge, l'utilisation GREP_OPTS=--color=autoprésente exactement les mêmes risques (problèmes par rapport aux scripts existants) que l'ajout en amont par défaut --color=auto. Ainsi, le commentaire selon lequel cela "crée plus de problèmes qu'il n'en résout" est complètement incorrect: aucun problème supplémentaire n'est créé.

Animal nominal
la source
3

La documentation que vous fournissez avec la première stratégie indique:

Veuillez utiliser un alias ou un script à la place. Par exemple, si grep est dans le répertoire '/ usr / bin', vous pouvez ajouter $ HOME / bin à votre CHEMIN et créer un script exécutable $ HOME / bin / grep contenant les éléments suivants:

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

Donc, si l'alias vous est impossible, le script wrapper est le seul moyen.

stderr
la source
C'est la stratégie 4 ... pas vraiment une réponse.
guettli
3

La raison pour laquelle la GREP_OPTIONSvariable est obsolète est qu'elle a tendance à causer des problèmes lorsqu'elle grepest appelée quelque part dans un script et que le script ne fonctionne pas avec les options alternatives qui proviennent de la variable. Si vous écrivez un script wrapper pour, grepvous rencontrez le même problème, sauf si vous lui donnez un nom différent .

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

Alternativement, stockez vos options préférées dans une variable. Dans les shells autres que zsh, cela est fastidieux si les options contiennent des caractères génériques ( \[*?), mais sinon vous pouvez simplement utiliser la variable sans guillemets pour obtenir une commande avec des arguments.

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

Notez que GNU et BSD grep peuvent traiter une arborescence de répertoires de manière récursive, ce qui réduit la nécessité de les findcombiner la grepplupart du temps.

Gilles 'SO- arrête d'être méchant'
la source
1
C'est la stratégie 4 ... pas vraiment une réponse.
guettli
@guettli, c'est la bonne réponse. Si vous voulez une commande avec un comportement différent grep, vous avez besoin d'une commande avec un nom différent, ou bien si vous gardez le même nom, vous casserez les scripts qui attendent le comportement d'origine / standard. C'est le plus propre et ne cause pas de problèmes supplémentaires .
Stéphane Chazelas
@ StéphaneChazelas oui tu as raison. C'est la bonne réponse selon votre point de vue.
guettli
1

Le plus simple est d'utiliser un alias (stratégie 3). Si vous vous souciez vraiment de la xargscommande, vous pouvez toujours la remplacer avec une fonction bash.

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
}

Mais ce n'est pas mieux que d'utiliser une commande wrapper qui semble être la solution recommandée par l' grepéquipe:

/usr/local/bin/grep:

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

À mon humble avis, vous devez contacter l' grepéquipe de développement pour leur demander de fournir un remplacement simple à la GREP_OPTIONSvariable qui permettra la couleur grepselon une variable d'environnement.

Il serait assez simple pour eux d'activer par défaut l' coloroption ou lorsque l'option GREP_COLORSa été définie.

Adam
la source
1
Merci pour "... vous devez contacter l'équipe de développeurs grep ...". Cela me donne une rétroaction positive. Maintenant, je sais que je ne suis pas le seul à penser qu'il manque quelque chose ici.
guettli
J'ai ajouté votre commentaire "... vous devez contacter l'équipe de développeurs grep ..." comme stratégie6 à la question. Jusqu'à présent, c'est ma réponse préférée.
guettli
0

C'est la solution de la première réponse de @NominalAnimal mais avec l'habituel grep: ...dans les avertissements (au lieu de /bin/grep: ...):

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
Kirill Bulygin
la source
Je sais écrire des wrappers. Un wrapper n'est pas une solution dans ce contexte.
guettli
@guettli Eh bien, la réponse n'était pas censée répondre précisément à votre situation ... Si les commentaires avaient les mêmes fonctionnalités de mise en forme que les réponses, ce serait un commentaire. (Et j'ai eu des modifications similaires rejetées car elles n'étaient pas voulues par l'auteur original ou quelque chose du genre.) Quant à votre situation, je pense qu'une réponse littérale appropriée à votre question est: qu'une autre "Stratégie NICE-and-EASY" n'existe pas.
Kirill Bulygin