Кольоровий вихід грепа: не GREP_OPTIONS, не псевдонім


10

Я хочу кольоровий вихід grep.

.... Але

  • Стратегія 1: GREP_OPTIONS. Але це застаріло. Див. Http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS з першого погляду виглядає як рішення, але це робить щось інше.
  • Стратегія 3: псевдонім. Це не працює find ... | xargs grep, оскільки xargs не оцінює псевдоніми.
  • Стратегія 4: Напишіть простий сценарій обгортки. Ні, я вважаю, що це занадто брудно і створює більше проблем, ніж вирішує.
  • Стратегія 5: виправлення вихідного коду
  • Стратегія 6: Зверніться до розробників grep, попросіть заміну GREP_OPTIONS
  • Стратегія NICE-and-EASY: ... цього немає. Я поняття не маю.

Як це вирішити?

Дякую за спробу допомогти!

... але я не можу дати нагороду

Називай мене грубим, зухвалим, образливим, образливим….

Я бачу лише заокруглення - рішення не має. Жодна відповідь не задовольнила запитання.

Дякую за ваші зусилля.


1
Ви відхилили дві пропозиції щодо використання сценарію обгортки (стратегія 4) як "насправді не відповіді". Чи можете ви описати, що тут "брудно", "клопітно" чи "насправді не відповідь"? Можливо, це окрема проблема, яку можна вирішити.
JigglyNaga

2
стратегія 5 - це виправлення вихідного коду та встановлення color_optionна2 ...
don_crissti

2
@JigglyNaga ось моє пояснення, чому сценарій обгортки не є рішенням. Наша команда управляє декількома серверами. На даний момент менше тисяч, але кількість збільшується. Так, ми використовуємо управління конфігурацією, і було б легко розгорнути сценарій для всіх. Але я хочу, щоб речі були легкими і зрозумілими (подумайте про нових членів команди. Я не хочу їх плутати). --colorВаріант вже має значення auto. Я просто не знаю, чому ти не можеш активувати його за замовчуванням.
guettli

Ви повинні використовувати стратегію 4 або 5 - я вважаю за краще стратегію 4 з мінімальним сценарієм тире / ш ( exec grep --color=auto "$@"), необов'язково з іншим іменем ( grepcабо colorgrep). Це має незначні накладні витрати (і немає додаткових одночасних процесів під час виконання). Причина, що ви позначили їх "недостатньо простою", - це те, що ви не вважаєте цю функцію достатньо корисною, щоб витратити (порівняно мало) разові зусилля на її реалізацію, і шукаєте, щоб хтось інший зробив це за вас. Через це ваші "не зовсім відповіді" коментарі до опублікованих відповідей досить грубі.
Номінальна тварина

1
@NominalAnimal Так, ви праві "не дуже відповідь" звучить грубо. Я не носій мови. Яке формулювання (передача того ж повідомлення) було б краще?
гуетлі

Відповіді:


13

Деякі з причин, за якими ОП заявила, що варіанти є непридатними, насправді не мають підстав. Тут я показую, які ефекти за допомогою стратегії 4 ОП мають:


У більшості дистрибутивів grepвстановлено в /bin(типовий) або /usr/bin(OpenSUSE, можливо, інших), а за замовчуванням PATHміститься /usr/local/binдо /binабо /usr/bin. Це означає , що якщо ви створюєте /usr/local/bin/grepз

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

де /bin/shє сумісна з POSIX оболонка, надана вашим розповсюдженням, як правило, баш або тире. Якщо grepє /usr/bin, то зробіть це

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

Витрати на цей сценарій мінімальні. У execзаяві означає , що інтерпретатор сценаріїв замінюється на grepдвійковий файл; це означає, що оболонка не залишається в пам'яті під час grepїї виконання. Таким чином, єдиний накладні витрати - це одне додаткове виконання інтерпретатора сценарію, тобто невелика затримка часу настінного годинника. Затримка приблизно постійною (змінюється тільки в залежності від того , grepі shвже в кеші сторінки чи ні, і від того, як смуга пропускання багато введення / виведення доступна), і не залежить від того, як довго grepвиконує або , скільки даних він обробляє.

Отже, як триває ця затримка, тобто накладні витрати, додані скриптом обгортки?

Щоб дізнатися це, створіть вищезгаданий сценарій та запустіть

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

На моїй машині перший займає 0,005с у режимі реального часу (за великої кількості пробіжок), тоді як другий займає 0,006с у реальному часі. Таким чином, витрати на використання обгортки на моїй машині становлять 0,001 (або менше) за виклик.

Це незначно.

Я також не бачу нічого «брудного» з цього приводу, тому що багато поширених додатків та утиліт використовують один і той же підхід. Щоб побачити список таких на вашій машині в /binі /usr/bin, просто запустіть

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

На моїй машині вище вихід включає в себе egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, і xfig, які я використовую досить часто. Якщо ви не вважаєте весь ваш дистрибутив "брудним", оскільки покладаєтесь на сценарії обгортки, у вас немає підстав вважати такі сценарії обгортки "брудними".


Що стосується проблем, такий сценарій обгортки може спричинити:

Якщо тільки людські користувачі (на відміну від скриптів) використовують версію Grep , що по замовчуванням кольору підтримки , якщо вихід є на термінал, то сценарій обгортка може бути ім'ям colorgrepабо cgrepабо незалежно від того, що ОП вважає за потрібне.

Це дозволяє уникнути всіх можливих проблем сумісності, оскільки поведінка grepне змінюється зовсім.


Увімкнення grepпараметрів за допомогою сценарію обгортки, але таким чином, щоб уникнути нових проблем:

Ми можемо легко переписати скрипт для обгортки, щоб підтримати звичай, GREP_OPTSнавіть якщо GREP_OPTIONSвін не підтримувався (як це вже застаріло). Таким чином користувачі можуть просто додати export "GREP_OPTIONS=--color=auto"або подібні до свого профілю. /usr/local/bin/grepє тоді

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

Зверніть увагу, що навколо немає жодних лапок $GREP_OPTIONS, щоб користувачі могли вказати кілька варіантів.

У моїй системі виконання time /usr/local/bin/grep --versionз GREP_OPTIONSпорожнім або з GREP_OPTIONS=--color=autoтакою ж швидкістю, як і попередня версія сценарію обгортки; тобто зазвичай виконується на одну мілісекунд більше, ніж звичайна grep.

Ця остання версія є тією, яку я особисто рекомендував використовувати.


Підсумовуючи стратегію 4 ОП:

  • рекомендується grepрозробниками

  • тривіально реалізувати (два рядки)

  • має незначні накладні витрати (одна мілісекунда додаткової затримки на виклик на цьому конкретному ноутбуці; легко перевіряється на кожній машині)

  • може бути реалізований як сценарій обгортки, який додає GREP_OPTSпідтримку (замінити застарілу / непідтримувану GREP_OPTIONS)

  • може бути реалізовано (як colorgrep/ cgrep), що взагалі не впливає на скрипти або існуючих користувачів

Оскільки це техніка, яка вже широко використовується в дистрибутивах Linux, це звичайна техніка і не "брудна".

Якщо його реалізувати як окрему обгортку ( colorgrep/ cgrep), вона не може створювати нових проблем, оскільки вона зовсім не впливає на grepповедінку. Якщо він реалізований як скрипт для обгортки, який додає GREP_OPTSпідтримку, використання GREP_OPTS=--color=autoмає точно такі ж ризики (wrt. Проблеми з існуючими сценаріями), що і для додавання за замовчуванням --color=auto. Таким чином, коментар, що це "створює більше проблем, ніж вирішує", є абсолютно невірним: додаткових проблем не створюється.


3

Документація, яку ви надаєте з першою стратегією, говорить:

Будь ласка, використовуйте псевдонім або сценарій. Наприклад, якщо grep знаходиться в каталозі '/ usr / bin', ви можете додати $ HOME / bin до вашої PATH та створити виконуваний сценарій $ HOME / bin / grep, що містить наступне:

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

Тож якщо псевдонім для вас неможливий, сценарій обгортки - це єдиний спосіб.


Це Стратегія 4… насправді не відповідь.
guettli

3

Причина GREP_OPTIONSзастарілої змінної полягає в тому, що вона, як правило, викликає проблеми, коли grepвикликається десь у скрипті, а сценарій не працює з альтернативними параметрами, що надходять із змінної. Якщо ви пишете скрипт для обгортки, grepто у вас є та сама проблема, якщо ви не дасте йому інше ім'я .

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

Крім того, зберігайте улюблені параметри у змінній. У оболонках, відмінних від zsh, це громіздко, якщо параметри містять символи підстановки ( \[*?), але в іншому випадку ви можете просто використовувати змінну, не цитовану, щоб отримати команду з аргументами.

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

Зауважте, що GNU та BSD grep можуть обробляти дерево каталогів рекурсивно, що зменшує потребу findв поєднанні з grepбільшою частиною часу.


1
Це Стратегія 4… насправді не відповідь.
guettli

@guettli, це правильна відповідь. Якщо ви хочете команду з іншою поведінкою grep, вам потрібна команда з іншим іменем, або, якщо ви збережете те саме ім'я, ви порушите скрипти, які очікують оригінальної / стандартної поведінки. Це найчистіше і не викликає додаткових проблем .
Стефан Шазелас

@ StéphaneChazelas так, ти прав. Це правильна відповідь відповідно до вашої точки зору.
guettli

1

Найпростіше використовувати псевдонім (стратегія 3). Якщо ви дійсно дбаєте про xargsкоманду, ви все одно можете її замінити за допомогою функції 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
}

Але це не краще, ніж використовувати команду обгортки, яка, здається, рекомендується grepкомандою:

/usr/local/bin/grep:

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

На мою скромну думку, вам слід зв’язатися з grepкомандою розробників, щоб попросити їх надати просту заміну GREP_OPTIONSзмінної, яка дозволить кольорові grepвідповідно до певної змінної середовища.

Для них було б досить просто включити colorопцію за замовчуванням або коли GREP_COLORSвстановлено значення.


1
Дякуємо вам за "... вам слід зв’язатися з командою розробників grep ...". Це дає мені позитивні відгуки. Тепер я знаю, що я не єдиний, хто думає, що чогось тут не вистачає.
guettli

Я додав ваш коментар "... вам слід зв’язатися з командою розробників grep ..." як стратегію6 до питання. На сьогодні це моя улюблена відповідь.
guettli

0

Це рішення з головної відповіді від @NominalAnimal, але зі звичайним grep: ...попередженням (замість /bin/grep: ...):

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

Я знаю, як писати обгортки. Обгортка не є рішенням у цьому контексті.
гуетлі

@guettli Добре, що відповідь не мала на меті вирішити саме вашу ситуацію ... Якщо коментарі мали ті самі функції форматування, що й відповіді, це був би коментар. (І у мене були відхилені подібні зміни, як це не було призначено оригінальним автором чи що-небудь.) Що стосується вашої ситуації, я думаю, що відповідна буквальна відповідь на ваше запитання полягає в тому, що інша "стратегія NICE-and-EASY" не існує.
Кирило Булигін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.