Salida grep coloreada: no GREP_OPTIONS no alias

10

Quiero salida de color de grep.

.... Pero

  • Estrategia 1: GREP_OPTIONS. Pero esto está en desuso. Ver http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS parece una solución a primera vista, pero esto hace algo diferente.
  • Estrategia 3: alias. Esto no funciona find ... | xargs grep, ya que xargs no evalúa los alias.
  • Estrategia 4: Escribe un script de envoltura simple. No, creo que esto es demasiado sucio y causa más problemas de los que resuelve.
  • Estrategia 5: parchear el código fuente
  • Estrategia 6: póngase en contacto con los desarrolladores de grep, solicite un reemplazo de GREP_OPTIONS
  • Estrategia NICE-and-EASY: ... esto falta. No tengo ni idea.

¿Cómo resolver esto?

¡Gracias por intentar ayudar!

... pero no puedo dar la recompensa

Llámame grosero, arogante, insultante, abusivo ...

Solo veo soluciones, no hay solución. Ninguna respuesta satisfizo la pregunta.

Gracias por tus esfuerzos.

guettli
fuente
1
Rechazó dos sugerencias para usar un script de envoltura (su Estrategia 4) como "no es realmente una respuesta". ¿Puede describir qué es "sucio", "problemático" o "realmente no es una respuesta" al respecto? Tal vez ese es un problema separado que se puede solucionar.
JigglyNaga
2
Estrategia 5 es parchear el código fuente y el conjunto color_optionde2 ...
don_crissti
2
@JigglyNaga aquí está mi explicación de por qué un script de contenedor no es una solución. Nuestro equipo gestiona varios servidores. Menos de mil en este momento, pero la cuenta está aumentando. Sí, utilizamos la gestión de configuración y sería fácil implementar un script para todos ellos. Pero quiero que las cosas sean fáciles y directas (piense en los nuevos miembros del equipo. No quiero confundirlos). La --coloropción ya tiene el valor auto. Simplemente no sé por qué no puedes activarlo de forma predeterminada.
guettli
Debería usar la estrategia 4 o 5: prefiero la estrategia 4 con un guión mínimo de guión / sh ( exec grep --color=auto "$@"), opcionalmente con un nombre diferente ( grepco colorgrep). Esto tiene una sobrecarga insignificante (y no hay procesos concurrentes adicionales en tiempo de ejecución). La razón por la que los ha etiquetado como "no es lo suficientemente fácil" es el hecho de que no ve esta característica lo suficientemente útil como para gastar el esfuerzo (relativamente pequeño) de una sola vez para implementarla, y está buscando a alguien más que lo haga por usted. Debido a esto, sus comentarios de "no es realmente una respuesta" a las respuestas publicadas son bastante groseros.
Nominal Animal
1
@NominalAnimal Sí, tienes razón "no es realmente una respuesta" suena grosero. No soy un hablante nativo. ¿Qué redacción (transferir el mismo mensaje) sería mejor?
guettli

Respuestas:

13

Algunas de las razones por las cuales OP ha declarado que las opciones no son adecuadas no tienen base en la realidad. Aquí, muestro qué tipo de efectos tiene la estrategia 4 de OP:


En la mayoría de las distribuciones, grepse instala en /bin(típico) o /usr/bin(OpenSUSE, tal vez otros), y por defecto PATHcontiene /usr/local/binantes /bino /usr/bin. Esto significa que si creas /usr/local/bin/grepcon

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

donde /bin/shes un shell compatible con POSIX proporcionado por su distribución, generalmente bash o dash. Si grepestá adentro /usr/bin, entonces haz eso

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

La sobrecarga de este script es mínima. La execdeclaración significa que el intérprete de script se reemplaza por el grepbinario; Esto significa que el shell no permanece en la memoria mientras grepse está ejecutando. Por lo tanto, la única sobrecarga es una ejecución adicional del intérprete de script, es decir, una pequeña latencia en el tiempo del reloj de pared. La latencia es aproximadamente constante (varía solo dependiendo de si grepya shestá en la memoria caché de la página o no, y de cuánto ancho de banda de E / S está disponible), y no depende de cuánto tiempo se grepejecuta o cuántos datos procesa.

Entonces, ¿cuánto dura esa latencia, es decir, la sobrecarga agregada por el script de envoltura?

Para averiguarlo, cree el script anterior y ejecute

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

En mi máquina, la primera toma 0.005s en tiempo real (en una gran cantidad de ejecuciones), mientras que la segunda toma 0.006s en tiempo real. Por lo tanto, la sobrecarga de usar el contenedor en mi máquina es 0.001s (o menos) por invocación.

Esto es insignificante.

Tampoco veo nada "sucio" sobre esto, porque muchas aplicaciones y utilidades comunes utilizan el mismo enfoque. Para ver la lista de tales en su máquina en /biny /usr/bin, simplemente ejecute

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

En mi máquina, la salida anterior incluye egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, y xfig, que yo uso bastante a menudo. A menos que considere toda su distribución "sucia" por confiar en los scripts de contenedor, no tiene ninguna razón para considerar tales scripts de contenedor "sucios".


En cuanto a los problemas, un script de contenedor puede causar:

Si sólo los usuarios humanos (a diferencia de los scripts) están utilizando la versión de grep que por defecto a la ayuda del color si la salida es a un terminal, entonces el guión envoltorio pueden ser nombrados colorgrepo cgrepo lo que sea el OP crea conveniente.

Esto evita todos los posibles problemas de compatibilidad, porque el comportamiento de grepno cambia en absoluto.


Habilitando grepopciones con un script de envoltura, pero de una manera que evita cualquier problema nuevo:

Podemos reescribir fácilmente la secuencia de comandos del contenedor para admitir una costumbre GREP_OPTSincluso si GREP_OPTIONSno fuera compatible (ya que está en desuso). De esta manera, los usuarios simplemente pueden agregarexport "GREP_OPTIONS=--color=auto" o similar a su perfil. /usr/local/bin/grepes entonces

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

Tenga en cuenta que no hay comillas $GREP_OPTIONS, por lo que los usuarios pueden especificar más de una opción.

En mi sistema, ejecutando time /usr/local/bin/grep --versionconGREP_OPTIONS vacío, o con GREP_OPTIONS=--color=auto, es tan rápido como la versión anterior del script de envoltura; es decir, normalmente tarda un milisegundo más en ejecutarse que simple grep.

Esta última versión es la que personalmente recomendaría para su uso.


En resumen, la estrategia 4 de OP:

  • ya está recomendado por grep desarrolladores

  • es trivial de implementar (dos líneas)

  • tiene una sobrecarga insignificante (latencia adicional de un milisegundo por invocación en esta computadora portátil en particular; se verifica fácilmente en cada máquina)

  • se puede implementar como un script de contenedor que agrega GREP_OPTSsoporte (para reemplazar obsoleto / no compatibleGREP_OPTIONS )

  • se puede implementar (como colorgrep/ cgrep) que no afecte a los scripts ni a los usuarios existentes

Debido a que es una técnica que ya se usa ampliamente en las distribuciones de Linux, es una técnica común y no "sucia".

Si se implementa como un contenedor separado ( colorgrep/ cgrep), no puede crear nuevos problemas ya que no afecta el grepcomportamiento en absoluto. Si se implementa como un script de envoltura que agrega GREP_OPTSsoporte, el uso GREP_OPTS=--color=autotiene exactamente los mismos riesgos (problemas de escritura con los scripts existentes) que el agregado predeterminado --color=auto. Por lo tanto, el comentario de que esto "crea más problemas de los que resuelve" es completamente incorrecto: no se crean problemas adicionales.

Animal nominal
fuente
3

La documentación que proporciona con la primera estrategia dice:

Utilice un alias o script en su lugar. Por ejemplo, si grep está en el directorio '/ usr / bin', puede anteponer $ HOME / bin a su RUTA y crear un script ejecutable $ HOME / bin / grep que contenga lo siguiente:

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

Entonces, si el alias es imposible para usted, la secuencia de comandos del contenedor es la única forma.

stderr
fuente
Esa es la Estrategia 4 ... no es realmente una respuesta.
guettli
3

La razón por la que la GREP_OPTIONSvariable está en desuso es que tiende a causar problemas cuando grepse llama a algún lugar en un script y el script no funciona con las opciones alternativas que provienen de la variable. Si escribe una secuencia de comandos de contenedor para grepentonces tiene el mismo problema, a menos que le asigne un nombre diferente .

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

Alternativamente, almacene sus opciones favoritas en una variable. En shells que no sean zsh, esto es engorroso si las opciones contienen caracteres comodín ( \[*?), pero de lo contrario, puede usar la variable sin comillas para obtener un comando con argumentos.

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

Tenga en cuenta que GNU y BSD grep pueden procesar un árbol de directorios de forma recursiva, lo que alivia la necesidad de findcombinarlo la grepmayor parte del tiempo.

Gilles 'SO- deja de ser malvado'
fuente
1
Esa es la Estrategia 4 ... no es realmente una respuesta.
guettli
@guettli, esa es la respuesta correcta. Si desea un comando con un comportamiento diferente grep, necesita un comando con un nombre diferente, o si mantiene el mismo nombre, interrumpirá los scripts que esperan el comportamiento original / estándar. Esa es la más limpia y no causa problemas adicionales .
Stéphane Chazelas
@ StéphaneChazelas sí, tienes razón. Esta es la respuesta correcta según su punto de vista.
guettli
1

Lo más fácil es usar un alias (estrategia 3). Si realmente te importa el xargscomando, aún puedes anularlo con una función 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
}

Pero esto no es mejor que usar un comando wrapper que parece ser la solución recomendada por el grepequipo:

/usr/local/bin/grep:

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

En mi humilde opinión, debe ponerse en contacto con el grepequipo de desarrolladores para pedirles que proporcionen un reemplazo simple a la GREP_OPTIONSvariable que permitirá el color de grepacuerdo con alguna variable de entorno.

Sería bastante simple para ellos habilitar por defecto la coloropción o cuando GREP_COLORSse haya configurado.

Adán
fuente
1
Gracias por "... deberías contactar al equipo de desarrolladores de grep ...". Esto me da comentarios positivos. Ahora sé que no soy el único que piensa que falta algo aquí.
guettli
Agregué su comentario "... debe comunicarse con el equipo de desarrolladores de grep ..." como estrategia6 a la pregunta. Hasta ahora esta es mi respuesta favorita.
guettli
0

Esta es la solución de la respuesta principal de @NominalAnimal pero con las grep: ...advertencias habituales (en lugar de /bin/grep: ...):

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
Kirill Bulygin
fuente
Sé cómo escribir envoltorios. Un contenedor no es una solución en este contexto.
guettli
@guettli Bueno, la respuesta no estaba destinada a abordar con precisión su situación ... Si los comentarios tuvieran las mismas características de formato que las respuestas, sería un comentario. (Y tuve ediciones similares rechazadas como no pretendían el autor original o algo así). En cuanto a su situación, creo que una respuesta literal adecuada a su pregunta es: que no existe otra "Estrategia AGRADABLE y FÁCIL".
Kirill Bulygin