Output grep colorato: non GREP_OPTIONS non alias


10

Voglio un output colorato di grep.

.... Ma

  • Strategia 1: GREP_OPTIONS. Ma questo è deprecato. Vedi http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS sembra una soluzione a prima vista, ma questo fa qualcosa di diverso.
  • Strategia 3: alias. Questo non funziona find ... | xargs grep, poiché xargs non valuta gli alias.
  • Strategia 4: scrivere un semplice script wrapper. No, penso che sia troppo sporco e crea più problemi di quanti ne risolva.
  • Strategia 5: patch il codice sorgente
  • Strategia 6: contatta gli sviluppatori grep, richiedi una sostituzione di GREP_OPTIONS
  • Strategia NICE-and-EASY: ... manca questo. Non ho idea.

Come risolverlo?

Grazie per aver tentato di aiutare!

... ma non posso dare la taglia

Chiamami maleducato, arrogante, offensivo, offensivo ...

Vedo solo soluzioni: nessuna soluzione. Nessuna risposta ha soddisfatto la domanda.

Grazie per i tuoi sforzi.


1
Hai rifiutato due suggerimenti per utilizzare uno script wrapper (la tua strategia 4) come "non proprio una risposta". Puoi descrivere cosa è "sporco", "problematico" o "non proprio una risposta" al riguardo? Forse è un problema separato che può essere risolto.
JigglyNaga,

2
la strategia 5 è patch il codice sorgente e impostato color_optionsu2 ...
don_crissti

2
@JigglyNaga ecco la mia spiegazione del perché uno script wrapper non è una soluzione. Il nostro team gestisce diversi server. Meno di mille al momento, ma il conteggio è in aumento. Sì, utilizziamo la gestione della configurazione e sarebbe facile distribuire uno script a tutti loro. Ma voglio che le cose siano facili e dirette (pensa ai nuovi membri del team. Non voglio confonderli). L' --coloropzione ha già il valore auto. Non so perché non puoi attivarlo per impostazione predefinita.
Guettli,

Dovresti usare la strategia 4 o 5 - Preferirei la strategia 4 con un trattino minimo / sh script ( exec grep --color=auto "$@"), facoltativamente con un nome diverso ( grepco colorgrep). Questo ha un sovraccarico neglible (e nessun processo concomitante extra in fase di esecuzione). Il motivo per cui li hai etichettati "non abbastanza facili" è il fatto che non vedi questa funzione abbastanza utile da dedicare (relativamente poco) uno sforzo una tantum per implementarla e stai cercando qualcun altro che lo faccia per te. Per questo motivo, i tuoi commenti "non proprio una risposta" alle risposte postate sono piuttosto scortesi.
Animale nominale

1
@NominalAnimal Sì, hai ragione "non proprio una risposta" suona scortese. Non sono un madrelingua. Quale formulazione (trasferire lo stesso messaggio) sarebbe meglio?
Guettli,

Risposte:


13

Alcuni dei motivi per cui OP ha dichiarato che le opzioni sono inadatte non hanno alcuna base nella realtà. Qui, mostro che tipo di effetti ha la strategia 4 di OP:


Nella maggior parte delle distribuzioni, grepè installato in /bin(tipico) o /usr/bin(OpenSUSE, forse altri) e il valore predefinito PATHcontiene /usr/local/binprima /bino /usr/bin. Questo significa che se crei /usr/local/bin/grepcon

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

dove si /bin/shtrova una shell compatibile con POSIX fornita dalla tua distribuzione, di solito bash o dash. Se grepè dentro /usr/bin, allora fallo

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

Il sovraccarico di questo script è minimo. L' execistruzione indica che l'interprete di script è sostituito dal grepbinario; questo significa che la shell non rimane in memoria durante grepl'esecuzione. Pertanto, l'unico sovraccarico è un'esecuzione aggiuntiva dell'interprete di script, ovvero una piccola latenza nel tempo dell'orologio da parete. La latenza è approssimativamente costante (varia solo in base al fatto grepche shsiano o meno nella cache della pagina e in base alla larghezza di banda di I / O disponibile) e non dipende dalla durata di grepesecuzione o dalla quantità di dati che elabora.

Quindi, quanto dura questa latenza, ovvero l'overhead aggiunto dallo script wrapper?

Per scoprirlo, crea lo script sopra ed esegui

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

Sulla mia macchina, il primo impiega 0,005 secondi in tempo reale (attraverso un gran numero di cicli), mentre il secondo impiega 0,006 secondi in tempo reale. Pertanto, il sovraccarico dell'uso del wrapper sulla mia macchina è di 0,001 secondi (o meno) per invocazione.

Questo è insignificante.

Inoltre, non riesco a vedere nulla di "sporco" al riguardo, perché molte applicazioni e utilità comuni utilizzano lo stesso approccio. Per vedere l'elenco di tali sul tuo computer in , /bine /usr/binbasta eseguire

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

Sulla mia macchina, l'uscita di cui sopra comprende egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, e xfig, che io uso molto spesso. A meno che non consideri la tua intera distribuzione "sporca" per fare affidamento sugli script wrapper, non hai motivo di considerare tali script wrapper "sporchi".


Per quanto riguarda i problemi, uno script wrapper può causare:

Se solo gli utenti umani (al contrario degli script) stanno usando la versione di grep che per impostazione predefinita supporta il colore se l'output è su un terminale, allora lo script wrapper può essere nominato colorgrepo come cgrepl'OP ritiene opportuno.

Questo evita tutti i possibili problemi di compatibilità, perché il comportamento di grepnon cambia affatto.


Abilitazione delle grepopzioni con uno script wrapper, ma in modo da evitare eventuali nuovi problemi:

Possiamo facilmente riscrivere lo script wrapper per supportare una personalizzazione GREP_OPTSanche se GREP_OPTIONSnon fosse supportata (in quanto è già obsoleta). In questo modo gli utenti possono semplicemente aggiungere export "GREP_OPTIONS=--color=auto"o simili al proprio profilo. /usr/local/bin/grepè poi

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

Nota che non ci sono virgolette in giro $GREP_OPTIONS, quindi gli utenti possono specificare più di un'opzione.

Sul mio sistema, l'esecuzione time /usr/local/bin/grep --versioncon GREP_OPTIONSvuoto o con GREP_OPTIONS=--color=autoè veloce quanto la versione precedente dello script wrapper; cioè, in genere richiede un millisecondo in più per l'esecuzione rispetto alla semplice grep.

Quest'ultima versione è quella che raccomanderei personalmente per l'uso.


In sintesi, la strategia 4 di OP:

  • è aready raccomandato dagli grepsviluppatori

  • è banale da implementare (due righe)

  • ha un sovraccarico insignificante (un millesimo di secondo in più per invocazione su questo particolare laptop; facilmente verificabile su ogni macchina)

  • può essere implementato come uno script wrapper che aggiunge GREP_OPTSsupporto (per sostituire deprecato / non supportato GREP_OPTIONS)

  • può essere implementato (come colorgrep/ cgrep) che non influisce affatto sugli script o sugli utenti esistenti

Poiché è una tecnica che è già ampiamente utilizzata nelle distribuzioni Linux, è una tecnica comune e non "sporca".

Se implementato come wrapper separato ( colorgrep/ cgrep), non può creare nuovi problemi poiché non influisce affatto sul grepcomportamento. Se implementato come uno script wrapper che aggiunge GREP_OPTSsupporto, l'utilizzo GREP_OPTS=--color=autoha esattamente gli stessi rischi (problemi wrt. Con script esistenti) che l'upstream aggiungendo default --color=auto. Pertanto, il commento che questo "crea più problemi di quanti ne risolva" è completamente errato: non vengono creati altri problemi.


3

La documentazione fornita con la prima strategia dice:

Utilizzare invece un alias o uno script. Ad esempio, se grep si trova nella directory '/ usr / bin' puoi anteporre $ HOME / bin al tuo PERCORSO e creare uno script eseguibile $ HOME / bin / grep contenente quanto segue:

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

Quindi se l'alias è impossibile per te, lo script wrapper è l'unico modo.


Questa è la strategia 4 ... non proprio una risposta.
Guettli,

3

Il motivo per cui la GREP_OPTIONSvariabile è deprecata è che tende a causare problemi quando grepviene chiamato da qualche parte in uno script e lo script non funziona con le opzioni alternative che provengono dalla variabile. Se scrivi uno script wrapper per grepallora hai lo stesso problema, a meno che tu non gli dia un nome diverso .

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

In alternativa, memorizza le tue opzioni preferite in una variabile. In shell diverse da zsh, questo è ingombrante se le opzioni contengono caratteri jolly ( \[*?), ma per il resto puoi semplicemente usare la variabile non quotata per ottenere un comando con argomenti.

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

Si noti che GNU e BSD grep possono elaborare un albero di directory in modo ricorsivo, il che allevia la necessità findin combinazione con la grepmaggior parte del tempo.


1
Questa è la strategia 4 ... non proprio una risposta.
Guettli,

@guettli, questa è la risposta corretta. Se si desidera un comando con un comportamento diverso grep, è necessario un comando con un nome diverso, oppure se si mantiene lo stesso nome, si romperanno gli script che prevedono il comportamento originale / standard. Questo è il più pulito e non causa ulteriori problemi .
Stéphane Chazelas,

@ StéphaneChazelas sì, hai ragione. Questa è la risposta corretta secondo il tuo punto di vista.
Guettli,

1

La cosa più semplice è usare un alias (strategia 3). Se ti interessa davvero il xargscomando, puoi comunque sovrascriverlo con una funzione 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
}

Ma questo non è meglio dell'uso di un comando wrapper che sembra essere la soluzione consigliata dal grepteam:

/usr/local/bin/grep:

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

A mio modesto parere, dovresti contattare il grepteam di sviluppatori per chiedere loro di fornire una semplice sostituzione alla GREP_OPTIONSvariabile che abiliterà il colore in grepbase ad alcune variabili d'ambiente.

Sarebbe abbastanza semplice per loro abilitare di default l' coloropzione o quando GREP_COLORSè stata impostata.


1
Grazie per "... dovresti contattare il team di sviluppatori grep ...". Questo mi dà un feedback positivo. Ora so che non sono l'unico a pensare che manchi qualcosa qui.
Guettli,

Ho aggiunto il tuo commento "... dovresti contattare il team di sviluppatori grep ..." come strategia6 alla domanda. Fino ad ora questa è la mia risposta preferita.
Guettli,

0

Questa è la soluzione dalla risposta principale di @NominalAnimal ma con i soliti grep: ...avvisi (anziché /bin/grep: ...):

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

So scrivere involucri. Un wrapper non è una soluzione in questo contesto.
Guettli,

@guettli Beh, la risposta non era pensata per affrontare con precisione la tua situazione ... Se i commenti avessero le stesse caratteristiche di formattazione delle risposte, sarebbe un commento. (E ho avuto modifiche simili rifiutate perché non volute dall'autore originale o qualcosa del genere.) Per quanto riguarda la tua situazione, penso che una risposta letterale adeguata alla tua domanda sia: che non esiste un'altra "Strategia NICE-and-EASY".
Kirill Bulygin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.