Saída grep colorida: não GREP_OPTIONS nem alias

10

Quero saída colorida de grep.

.... Mas

  • Estratégia 1: GREP_OPTIONS. Mas isso está obsoleto. Consulte http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS parece uma solução à primeira vista, mas isso faz algo diferente.
  • Estratégia 3: alias. Isso não funciona find ... | xargs grep, pois o xargs não avalia aliases.
  • Estratégia 4: Escreva um script de wrapper simples. Não, acho que isso é muito sujo e cria mais problemas do que resolve.
  • Estratégia 5: corrigir o código fonte
  • Estratégia 6: entre em contato com desenvolvedores grep, solicite uma substituição de GREP_OPTIONS
  • Estratégia AGRADÁVEL e FÁCIL: ... isso está faltando. Eu não tenho idéia.

Como resolver isso?

Obrigado por tentar ajudar!

... mas não posso dar a recompensa

Chame-me rude, arogante, insultuoso, abusivo ....

Só vejo soluções alternativas - sem solução. Nenhuma resposta satisfez a pergunta.

Obrigado por seus esforços.

guettli
fonte
1
Você rejeitou duas sugestões para usar um script de wrapper (sua Estratégia 4) como "não é realmente uma resposta". Você pode descrever o que é "sujo", "problemático" ou "não é realmente uma resposta" sobre isso? Talvez esse seja um problema separado que possa ser contornado.
JigglyNaga
2
estratégia 5 é corrigir o código fonte e conjunto color_optionde2 ...
don_crissti
2
@JigglyNaga, aqui está a minha explicação por que um script wrapper não é uma solução. Nossa equipe gerencia vários servidores. Menos de mil no momento, mas a contagem está aumentando. Sim, usamos o gerenciamento de configuração e seria fácil implantar um script em todos eles. Mas quero que as coisas sejam fáceis e diretas (pense em novos membros da equipe. Não quero confundi-los). A --coloropção já tem o valor auto. Só não sei por que você não pode ativá-lo por padrão.
guettli
Você deve usar a estratégia 4 ou 5 - eu prefiro a estratégia 4 com um script dash / sh mínimo ( exec grep --color=auto "$@"), opcionalmente com um nome diferente ( grepcou colorgrep). Isso tem sobrecarga negligenciável (e nenhum processo simultâneo extra em tempo de execução). A razão pela qual você os rotulou "não é fácil o suficiente" é o fato de você não ver esse recurso útil o suficiente para gastar o (relativamente pequeno) esforço único para implementá-lo e está procurando alguém para fazer isso por você. Por esse motivo, seus comentários "não são realmente uma resposta" para as respostas postadas são bastante rudes.
Animal Nominal
1
@NominalAnimal Sim, você está certo "não é realmente uma resposta" parece rude. Eu não sou um falante nativo. Qual redação (transferir a mesma mensagem) seria melhor?
guettli

Respostas:

13

Alguns dos motivos pelos quais a OP declarou que as opções são inadequadas não têm base na realidade. Aqui, mostro que tipo de efeitos usando a estratégia 4 do OP:


Na maioria das distribuições, grepé instalado em /bin(típico) ou /usr/bin(OpenSUSE, talvez outros), e o padrão PATHcontém /usr/local/binantes /binou /usr/bin. Isso significa que se você criar /usr/local/bin/grepcom

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

onde /bin/shé um shell compatível com POSIX fornecido pela sua distribuição, geralmente bash ou dash. Se grepestiver dentro /usr/bin, faça isso

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

A sobrecarga desse script é mínima. A execdeclaração significa que o interpretador de script é substituído pelo grepbinário; isso significa que o shell não permanece na memória enquanto grepestá sendo executado. Portanto, a única sobrecarga é uma execução extra do interpretador de script, ou seja, uma pequena latência no tempo do relógio de parede. A latência é mais ou menos constante (só varia dependendo se grepe shjá estão no cache de página ou não, e de quanto I / O largura de banda disponível), e não depende de quanto tempo grepexecuta ou quantos dados que processa.

Então, quanto tempo dura essa latência, ou seja, a sobrecarga adicionada pelo script do wrapper?

Para descobrir, crie o script acima e execute

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

Na minha máquina, o primeiro leva 0,005s em tempo real (em um grande número de execuções), enquanto o último leva 0,006s em tempo real. Portanto, a sobrecarga do uso do wrapper na minha máquina é de 0,001s (ou menos) por chamada.

Isso é insignificante.

Também não consigo ver nada "sujo" sobre isso, porque muitos aplicativos e utilitários comuns usam a mesma abordagem. Para ver a lista deles na sua máquina /bine /usr/bin, basta executar

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

Na minha máquina, a saída acima inclui egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, e xfig, que eu uso com bastante frequência. A menos que você considere sua distribuição inteira "suja" por confiar em scripts de wrapper, você não tem motivos para considerar esses scripts de wrapper "sujos".


Quanto aos problemas que um script de wrapper pode causar:

Se apenas usuários humanos (em oposição a scripts) estiverem usando a versão do grep que possui como padrão o suporte a cores se a saída for para um terminal, o script do wrapper poderá ser nomeado colorgrepou cgrepou o que o OP considerar adequado.

Isso evita todos os possíveis problemas de compatibilidade, porque o comportamento de grepnão muda.


Ativando grepopções com um script de wrapper, mas de uma maneira que evite novos problemas:

Podemos reescrever facilmente o script do wrapper para suportar um costume, GREP_OPTSmesmo que GREP_OPTIONSnão tenha sido suportado (como ele já foi descontinuado). Dessa forma, os usuários podem simplesmente adicionar export "GREP_OPTIONS=--color=auto"ou semelhante ao seu perfil. /usr/local/bin/grepé então

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

Observe que não há aspas $GREP_OPTIONS, para que os usuários possam especificar mais de uma opção.

No meu sistema, executar time /usr/local/bin/grep --versioncom GREP_OPTIONSvazio, ou com GREP_OPTIONS=--color=auto, é tão rápido quanto a versão anterior do script do wrapper; isto é, normalmente leva um milissegundo a mais para ser executado do que simples grep.

Esta última versão é a que eu pessoalmente recomendo para uso.


Em resumo, a estratégia 4 do OP:

  • já é recomendado pelos grepdesenvolvedores

  • é trivial de implementar (duas linhas)

  • possui sobrecarga insignificante (uma latência extra de milissegundos por chamada neste laptop em particular; facilmente verificável em cada máquina)

  • pode ser implementado como um script de wrapper que adiciona GREP_OPTSsuporte (para substituir obsoleto / não suportado GREP_OPTIONS)

  • pode ser implementado (como colorgrep/ cgrep) que não afeta scripts ou usuários existentes

Por ser uma técnica amplamente utilizada nas distribuições Linux, é uma técnica comum e não "suja".

Se implementado como um wrapper separado ( colorgrep/ cgrep), não poderá criar novos problemas, pois não afeta o grepcomportamento. Se implementado como um script de wrapper que adiciona GREP_OPTSsuporte, o uso GREP_OPTS=--color=autotem exatamente os mesmos riscos (problemas graves com scripts existentes) que a adição de upstream padrão --color=autoteria. Portanto, o comentário de que isso "cria mais problemas do que resolve" é completamente incorreto: nenhum problema adicional é criado.

Animal Nominal
fonte
3

A documentação que você fornece com a primeira estratégia diz:

Por favor, use um apelido ou script. Por exemplo, se grep estiver no diretório '/ usr / bin', você poderá acrescentar $ HOME / bin ao seu PATH e criar um script executável $ HOME / bin / grep contendo o seguinte:

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

Portanto, se o alias for impossível para você, o script do wrapper é a única maneira.

stderr
fonte
Essa é a Estratégia 4 ... não é realmente uma resposta.
guettli
3

A razão pela qual a GREP_OPTIONSvariável foi descontinuada é que ela tende a causar problemas quando grepé chamada em algum lugar de um script e o script não funciona com as opções alternativas que vêm da variável. Se você escrever um script de wrapper grep, terá o mesmo problema, a menos que dê um nome diferente .

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

Como alternativa, armazene suas opções favoritas em uma variável. Em shells diferentes de zsh, isso é complicado se as opções contiverem caracteres curinga ( \[*?), mas, caso contrário, você poderá usar a variável não citada para obter um comando com argumentos.

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

Note que o GNU e o BSD grep podem processar uma árvore de diretórios recursivamente, o que alivia a necessidade findem combinação com a grepmaior parte do tempo.

Gilles 'SO- parar de ser mau'
fonte
1
Essa é a Estratégia 4 ... não é realmente uma resposta.
guettli
Guettli @, essa é a resposta correta. Se você deseja um comando com um comportamento diferente grep, precisará de um comando com um nome diferente ou, se mantiver o mesmo nome, interromperá os scripts que esperam o comportamento original / padrão. Essa é a mais limpa e não causa problemas adicionais .
Stéphane Chazelas
@ StéphaneChazelas sim, você está certo. Esta é a resposta correta de acordo com o seu ponto de vista.
guettli
1

O mais fácil é usar um alias (estratégia 3). Se você realmente se importa com o xargscomando, ainda pode substituí-lo por uma função 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
}

Mas isso não é melhor do que usar um comando wrapper que parece ser a solução recomendada pela grepequipe:

/usr/local/bin/grep:

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

Na minha humilde opinião, você deve entrar em contato com a grepequipe de desenvolvedores para solicitar uma substituição simples da GREP_OPTIONSvariável que habilitará a cor de grepacordo com alguma variável de ambiente.

Seria bastante simples para eles habilitar por padrão a coloropção ou quando GREP_COLORSela foi definida.

Adão
fonte
1
Obrigado por "... você deve entrar em contato com a equipe de desenvolvedores grep ...". Isso me dá um feedback positivo. Agora eu sei que não sou o único que pensa que algo está faltando aqui.
guettli
Eu adicionei seu comentário "... você deve entrar em contato com a equipe de desenvolvedores grep ..." como estratégia6 para a pergunta. Até agora, esta é a minha resposta favorita.
guettli
0

Esta é a solução da resposta principal de @NominalAnimal, mas com o habitual grep: ...nos avisos (em vez de /bin/grep: ...):

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
Kirill Bulygin
fonte
Eu sei escrever invólucros. Um wrapper não é uma solução nesse contexto.
7279 guettli
@ guettli Bem, a resposta não foi feita para resolver exatamente a sua situação ... Se os comentários tivessem os mesmos recursos de formatação que as respostas, isso seria um comentário. (E tive edições semelhantes rejeitadas por não ter sido pretendida pelo autor original ou algo assim.) Quanto à sua situação, acho que uma resposta literal adequada à sua pergunta é: que não existe outra "Estratégia AGRADÁVEL E FÁCIL".
Kirill Bulygin