Saída grep colorida: não GREP_OPTIONS não é apelido

7

Eu quero uma saída colorida de grep .

... Mas

  • Estratégia 1: GREP_OPTIONS. Mas isso está obsoleto. Consulte o link
  • Stragegy 2: GREP_COLORS parece uma solução à primeira vista, mas isso faz algo diferente.
  • Estratégia 3: alias. Isso não funciona para find ... | xargs grep , pois o xargs não avalia aliases.
  • Estratégia 4: escreva um script simples de wrapper. Não, acho que isso é muito sujo e causa mais problemas do que resolve.
  • Estratégia 5: corrigir o código-fonte
  • Estratégia 6: Entre em contato com desenvolvedores do grep, solicite a substituição de GREP_OPTIONS
  • Estratégia NICE-and-EASY: ... isso está faltando. Eu não tenho ideia.

Como resolver isso?

Obrigado por tentar ajudar!

... mas eu não posso dar a recompensa

Me chame de rude, arrogante, insultante, abusivo ...

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

Obrigado pelos seus esforços.

    
por guettli 13.03.2017 / 11:34

4 respostas

6

Algumas das razões pelas quais OP afirmou que as opções são inadequadas não têm base na realidade. Aqui, eu mostro que tipo de efeitos usando a estratégia 4 do OP tem:

Na maioria das distribuições, grep está instalado em /bin (típico) ou /usr/bin (OpenSUSE, talvez outros) e o padrão PATH contém /usr/local/bin antes de /bin ou /usr/bin . Isto significa que se você criar /usr/local/bin/grep com

#!/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 grep estiver em /usr/bin , faça isso

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

A sobrecarga desse script é mínima. A instrução exec significa que o interpretador de script é substituído pelo grep binário; isso significa que o shell não permanece na memória enquanto grep está sendo executado. Assim, a única sobrecarga é uma execução extra do interpretador de script, isto é, uma pequena latência no tempo de relógio de parede. A latência é aproximadamente constante (varia somente dependendo se grep e sh já estão no cache de páginas ou não, e em quanto de largura de banda de E / S está disponível) e não depende de quanto tempo grep é executado ou quantos dados processa.

Então, quanto tempo dura essa latência, ou seja, a sobrecarga adicionada pelo script 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 (através de um grande número de corridas), enquanto o último leva 0,006s em tempo real. Assim, a sobrecarga de usar o wrapper na minha máquina é 0,001s (ou menos) por invocação.

Isso é insignificante.

Eu 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 de tal na sua máquina em /bin e /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 toda a sua distribuição "suja" por depender de scripts de wrapper, você não tem motivos para considerar esses scripts de wrapper "sujos".

Quanto a problemas como esse script de wrapper pode causar:

Se apenas usuários humanos (em oposição a scripts) estiverem usando a versão do grep que padroniza o suporte a cores se a saída for para um terminal, o script do wrapper pode ser denominado colorgrep ou cgrep ou qualquer que seja o OP ajuste.

Isso evita todos os possíveis problemas de compatibilidade, porque o comportamento de grep não é alterado.

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

Podemos facilmente reescrever o script wrapper para suportar um GREP_OPTS personalizado, mesmo se GREP_OPTIONS não fosse suportado (pois já está obsoleto). Dessa forma, os usuários podem simplesmente adicionar export "GREP_OPTIONS=--color=auto" ou semelhante ao perfil deles. /usr/local/bin/grep é então

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

Observe que não há cotações em torno de $GREP_OPTIONS , para que os usuários possam especificar mais de uma opção.

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

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

Em resumo, a estratégia do OP 4:

  • é recomendado por grep desenvolvedores

  • é trivial para implementar (duas linhas)

  • tem uma sobrecarga insignificante (um milissegundo de latência extra por chamada neste laptop em particular; facilmente verificado em cada máquina)

  • pode ser implementado como um script de wrapper que adiciona GREP_OPTS support (para substituir GREP_OPTIONS com descontinuidade / sem suporte)

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

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

Se implementado como um wrapper separado ( colorgrep / cgrep ), ele não poderá criar novos problemas, pois não afeta o comportamento grep . Se implementado como um script de wrapper que adiciona GREP_OPTS support, usar GREP_OPTS=--color=auto tem exatamente os mesmos riscos (wrt. Problemas com scripts existentes) que o upstream adicionaria o padrão --color=auto . Assim, o comentário de que isso "cria mais problemas do que resolve" está completamente incorreto: nenhum problema adicional é criado.

    
por 20.03.2017 / 15:39
4

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

Please use an alias or script instead. For example, if grep is in the directory ‘/usr/bin’ you can prepend $HOME/bin to your PATH and create an executable script $HOME/bin/grep containing the following:

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

Então, se o alias for impossível para você, o script wrapper é o único caminho.

    
por 13.03.2017 / 14:42
4

A razão pela qual a variável GREP_OPTIONS está obsoleta é que ela tende a causar problemas quando grep é chamado em algum lugar em um script e o script não funciona com as opções alternativas que vêm da variável. Se você escrever um script wrapper para grep , então você tem o mesmo problema, a menos que você 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 que não sejam zsh, isso é complicado se as opções contiverem caracteres curinga ( \[*? ), mas, caso contrário, você pode simplesmente usar a variável sem aspas 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 de find em combinação com grep na maioria das vezes.

    
por 14.03.2017 / 02:45
1

O mais fácil é usar um alias (estratégia 3). Se você realmente se importa com o comando xargs , ainda pode sobrescrevê-lo com 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 equipe grep :

/usr/local/bin/grep:

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

Na minha humilde opinião, você deve entrar em contato com a equipe de desenvolvedores grep para pedir que eles forneçam uma substituição simples para a variável GREP_OPTIONS , que ativará a cor em grep de acordo com alguma variável de ambiente. / strong>

Seria bastante simples habilitar por padrão a opção color ou quando o GREP_COLORS foi definido.

    
por 19.03.2017 / 22:28