Wyjściowe kolorowe grep: Nie GREP_OPTIONS nie alias

10

Chcę kolorowe wyjście grep.

.... Ale

  • Strategia 1: GREP_OPTIONS. Ale to jest przestarzałe. Zobacz http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS na pierwszy rzut oka wyglądają jak rozwiązanie, ale robi to coś innego.
  • Strategia 3: alias. To nie działa find ... | xargs grep, ponieważ xargs nie ocenia aliasów.
  • Strategia 4: Napisz prosty skrypt opakowania. Nie, myślę, że jest to zbyt brudne i sprawia więcej problemów niż rozwiązuje.
  • Strategia 5: załóż kod źródłowy
  • Strategia 6: Skontaktuj się z programistami grep, poproś o zastąpienie GREP_OPTIONS
  • Strategia ŁADNE i ŁATWE: ... tego brakuje. Nie mam pojęcia.

Jak to rozwiązać?

Dziękujemy za próbę pomocy!

... ale nie mogę dać nagrody

Nazywaj mnie niegrzecznym, aroganckim, obraźliwym, obraźliwym ...

Widzę tylko obejścia - bez rozwiązania. Żadna odpowiedź nie zadawała pytania.

Dziękuję za Twój wysiłek.

guettli
źródło
1
Odrzuciłeś dwie sugestie dotyczące używania skryptu opakowania (Twoja strategia 4) jako „nie do końca odpowiedź”. Czy możesz opisać, co jest w tym „brudne”, „kłopotliwe” lub „nie do końca”? Może to osobny problem, który można obejść.
JigglyNaga,
2
strategia 5 łata kod źródłowy i ustawia color_optionna2 ...
don_crissti
2
@JigglyNaga tutaj jest moje wyjaśnienie, dlaczego skrypt otoki nie jest rozwiązaniem. Nasz zespół zarządza kilkoma serwerami. W tej chwili mniej niż tysiąc, ale liczba rośnie. Tak, korzystamy z zarządzania konfiguracją i wdrożenie wszystkich skryptów byłoby łatwe. Ale chcę, aby wszystko było łatwe i zrozumiałe (pomyśl o nowych członkach zespołu. Nie chcę ich mylić). --colorOpcja ma już wartość auto. Po prostu nie wiem, dlaczego nie możesz go aktywować domyślnie.
guettli
Powinieneś użyć strategii 4 lub 5 - wolałbym strategię 4 z minimalnym skryptem dash / sh ( exec grep --color=auto "$@"), opcjonalnie o innej nazwie ( grepclub colorgrep). Ma to nieistotny narzut (i brak dodatkowych współbieżnych procesów w czasie wykonywania). Powodem, dla którego określiłeś je jako „niełatwe”, jest to, że nie widzisz tej funkcji na tyle przydatnej, by poświęcić (stosunkowo mało) jednorazowego wysiłku na jej wdrożenie, i szukasz kogoś, kto zrobiłby to za Ciebie. Z tego powodu twoje komentarze „nie do końca na opublikowane odpowiedzi są dość niegrzeczne.
Nominal Animal
1
@NominalAnimal Tak, masz rację, „nie do końca odpowiedź” brzmi niegrzecznie. Nie jestem native speakerem. Które sformułowanie (przesyłanie tej samej wiadomości) byłoby lepsze?
guettli

Odpowiedzi:

13

Niektóre z powodów, dla których OP stwierdził, że opcje są nieodpowiednie, nie mają podstaw w rzeczywistości. Tutaj pokazuję, jakie efekty ma strategia OP 4:


W większości dystrybucji grepjest instalowany w /bin(typowy) lub /usr/bin(OpenSUSE, może inne) i domyślnie PATHzawiera /usr/local/binprzed /binlub /usr/bin. Oznacza to, że jeśli tworzysz za /usr/local/bin/greppomocą

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

gdzie /bin/shjest powłoka kompatybilna z POSIX dostarczana przez twoją dystrybucję, zwykle bash lub dash. Jeśli grepjest /usr/bin, to zrób to

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

Narzut tego skryptu jest minimalny. Te execśrodki oświadczenie, że interpreter skryptu jest zastąpione przez grepbinarnej; oznacza to, że powłoka nie pozostaje w pamięci podczas grepwykonywania. Zatem jedynym narzutem jest jedno dodatkowe wykonanie interpretera skryptu, tj. Małe opóźnienie w czasie zegara ściennego. Opóźnienie jest mniej więcej stała (zależy tylko od tego, czy grepi shjuż są w pamięci podręcznej stron, czy nie, i na ile I / O przepustowość jest dostępna), a nie zależy od tego, jak długo grepbędzie wykonywał lub jak dużo danych przetwarza.

Jak długo to opóźnienie, tj. Narzut dodany przez skrypt opakowania?

Aby się dowiedzieć, utwórz powyższy skrypt i uruchom

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

Na mojej maszynie pierwsza trwa 0,005 s w czasie rzeczywistym (w dużej liczbie przebiegów), podczas gdy druga trwa 0,006 s w czasie rzeczywistym. W związku z tym narzut związany z użyciem opakowania na mojej maszynie wynosi 0,001 s (lub mniej) na wywołanie.

To jest nieistotne.

Nie widzę też w tym nic „brudnego”, ponieważ wiele popularnych aplikacji i narzędzi używa tego samego podejścia. Aby zobaczyć listę takich na swoim komputerze w /bini /usr/bin, po prostu uruchom

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

Na moim komputerze, powyższy wyjściowy zawiera egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, i xfig, którego używam dość często. Jeśli nie uważasz całej dystrybucji za „brudną” za poleganie na skryptach opakowujących, nie masz powodu, aby uważać takie skrypty opakowujące za „brudne”.


Jeśli chodzi o problemy, taki skrypt opakowania może powodować:

Jeśli tylko użytkownicy człowieka (w przeciwieństwie do skryptów) używasz wersji grep że domyślnie wsparcia koloru jeśli wyjście jest do terminala, a następnie skrypt banderola może być nazwany colorgreplub cgrepczy cokolwiek PO uważa za stosowne.

Pozwala to uniknąć wszystkich możliwych problemów ze zgodnością, ponieważ zachowanie grepsię nie zmienia.


Włączanie grepopcji za pomocą skryptu opakowania, ale w sposób pozwalający uniknąć nowych problemów:

Możemy łatwo przepisać skrypt opakowania, aby obsługiwał niestandardowy, GREP_OPTSnawet jeśli GREP_OPTIONSnie był obsługiwany (ponieważ jest już przestarzały). W ten sposób użytkownicy mogą po prostu dodać export "GREP_OPTIONS=--color=auto"lub podobny profil. /usr/local/bin/grepjest wtedy

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

Zauważ, że nie ma żadnych cudzysłowów $GREP_OPTIONS, więc użytkownicy mogą określić więcej niż jedną opcję.

W moim systemie wykonywanie time /usr/local/bin/grep --versionz GREP_OPTIONSpustym lub z GREP_OPTIONS=--color=autojest tak samo szybkie, jak poprzednia wersja skryptu opakowania; tzn. zwykle zajmuje jedną milisekundę dłużej niż zwykły grep.

Ta ostatnia wersja jest tą, którą osobiście polecam do użytku.


Podsumowując, strategia OP 4:

  • jest zalecany przez grepprogramistów

  • jest prosty do wdrożenia (dwie linie)

  • ma nieznaczny narzut (dodatkowe milisekundowe opóźnienie na wywołanie na tym konkretnym laptopie; łatwe do zweryfikowania na każdym komputerze)

  • może być zaimplementowany jako skrypt otoki, który dodaje GREP_OPTSobsługę (zastępuje przestarzałe / nieobsługiwane GREP_OPTIONS)

  • można zaimplementować (jako colorgrep/ cgrep), co nie wpływa na skrypty ani istniejących użytkowników

Ponieważ jest to technika, która jest już powszechnie stosowana w dystrybucjach Linuksa, jest to technika powszechna, a nie „brudna”.

Jeśli zostanie zaimplementowany jako osobne opakowanie ( colorgrep/ cgrep), nie może tworzyć nowych problemów, ponieważ w ogóle nie wpływa na grepzachowanie. Jeśli zostanie zaimplementowany jako skrypt otoki, który dodaje GREP_OPTSobsługę, użycie GREP_OPTS=--color=automa dokładnie takie samo ryzyko (problemy z istniejącymi skryptami), jak w przypadku dodawania domyślnego --color=auto. Zatem komentarz, że „stwarza więcej problemów niż rozwiązuje” jest całkowicie niepoprawny: nie powstają dodatkowe problemy.

Nominalne zwierzę
źródło
3

Dokumentacja dostarczona z pierwszą strategią mówi:

Zamiast tego użyj aliasu lub skryptu. Na przykład, jeśli grep znajduje się w katalogu „/ usr / bin”, możesz dodać $ HOME / bin do ŚCIEŻKI i utworzyć skrypt wykonywalny $ HOME / bin / grep zawierający następujące elementy:

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

Jeśli więc alias jest dla Ciebie niemożliwy, skrypt opakowania jest jedynym sposobem.

stderr
źródło
To jest strategia 4 ... nie do końca odpowiedź.
guettli
3

Powodem GREP_OPTIONSzmienna jest przestarzała jest to, że ma tendencję do problemów Bo kiedy grepnazywa się gdzieś w skrypcie i skrypt nie działa z alternatywnych opcji, które pochodzą ze zmiennej. Jeśli napiszesz skrypt opakowania grep, masz ten sam problem, chyba że nadasz mu inną nazwę .

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

Możesz też zapisać swoje ulubione opcje w zmiennej. W powłokach innych niż zsh jest to uciążliwe, jeśli opcje zawierają znaki wieloznaczne ( \[*?), ale w przeciwnym razie możesz po prostu użyć zmiennej bez cudzysłowu, aby uzyskać polecenie z argumentami.

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

Zauważ, że GNU i BSD grep mogą rekurencyjnie przetwarzać drzewo katalogów, co eliminuje potrzebę findw połączeniu z grepwiększością czasu.

Gilles „SO- przestań być zły”
źródło
1
To jest strategia 4 ... nie do końca odpowiedź.
guettli
@ guettli, to poprawna odpowiedź. Jeśli chcesz komendy o innym, greppodobnym zachowaniu , potrzebujesz komendy o innej nazwie, lub jeśli zachowasz tę samą nazwę, złamiesz skrypty, które oczekują oryginalnego / standardowego zachowania. To jest najczystsze i nie powoduje dodatkowych problemów .
Stéphane Chazelas
@ StéphaneChazelas tak masz rację. To jest prawidłowa odpowiedź według twojego punktu widzenia.
guettli
1

Najłatwiej jest użyć aliasu (strategia 3). Jeśli naprawdę zależy ci na xargspoleceniu, możesz go zastąpić za pomocą funkcji 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
}

Nie jest to jednak lepsze niż użycie polecenia otoki, które wydaje się być zalecanym przez grepzespół rozwiązaniem :

/usr/local/bin/grep:

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

Moim skromnym zdaniem powinieneś skontaktować się z grepzespołem programistów, aby poprosić ich o prostą zamianę GREP_OPTIONSzmiennej, która umożliwi kolor grepzgodnie z pewną zmienną środowiskową.

Byłoby dla nich dość proste, aby domyślnie włączyć coloropcję lub kiedy GREP_COLORSzostała ustawiona.

Adam
źródło
1
Dziękujemy za „... powinieneś skontaktować się z zespołem programistów grep ...”. To daje mi pozytywne opinie. Teraz wiem, że nie tylko ja uważam, że czegoś tu brakuje.
guettli
Dodałem komentarz „... powinieneś skontaktować się z zespołem programistów grep ...” jako strategią6 do pytania. Do tej pory to moja ulubiona odpowiedź.
guettli
0

Oto rozwiązanie z górnej odpowiedzi @NominalAnimal, ale ze zwykłymi grep: ...ostrzeżeniami (zamiast /bin/grep: ...):

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
Kirill Bulygin
źródło
Wiem, jak pisać opakowania. Opakowanie nie jest rozwiązaniem w tym kontekście.
guettli
@guettli Cóż, odpowiedź nie miała na celu dokładnie opisać twojej sytuacji ... Jeśli komentarze miałyby takie same funkcje formatowania jak odpowiedzi, byłby to komentarz. (I miałem podobne zmiany odrzucone, jak nie zamierzone przez oryginalnego autora, czy coś takiego.) Jeśli chodzi o twoją sytuację, myślę, że właściwa dosłowna odpowiedź na twoje pytanie brzmi: że inna „Strategia ŁADNA i ŁATWA” nie istnieje.
Kirill Bulygin